From 92788d9f16c113ba8067699715b83844dabe7ddc Mon Sep 17 00:00:00 2001 From: Elad Dekel <74513560+eladdekel@users.noreply.github.com> Date: Wed, 15 May 2024 21:40:49 -0400 Subject: [PATCH] implementation of native iOS app --- .../zeroone-app.xcodeproj/project.pbxproj | 415 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 5 + .../UserInterfaceState.xcuserstate | Bin 0 -> 69795 bytes .../WorkspaceSettings.xcsettings | 14 + .../xcdebugger/Breakpoints_v2.xcbkptlist | 6 + .../xcschemes/xcschememanagement.plist | 14 + .../zeroone-app/zeroone-app/AppDelegate.swift | 36 ++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 14 + .../Assets.xcassets/AppIcon.appiconset/O.png | Bin 0 -> 39280 bytes .../zeroone-app/Assets.xcassets/Contents.json | 6 + .../vector.imageset/Contents.json | 12 + .../vector.imageset/vector.svg | 5 + .../zeroone-app/AudioRecording.swift | 67 +++ .../Base.lproj/LaunchScreen.storyboard | 25 ++ .../zeroone-app/Base.lproj/Main.storyboard | 127 ++++++ .../ios/zeroone-app/zeroone-app/Info.plist | 27 ++ .../zeroone-app/SceneDelegate.swift | 52 +++ .../zeroone-app/ViewController.swift | 366 +++++++++++++++ 21 files changed, 1217 insertions(+) create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.pbxproj create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcuserdata/eladdekel.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcuserdata/eladdekel.xcuserdatad/WorkspaceSettings.xcsettings create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/xcuserdata/eladdekel.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/xcuserdata/eladdekel.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/AppDelegate.swift create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AppIcon.appiconset/O.png create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/Contents.json create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/vector.imageset/Contents.json create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/vector.imageset/vector.svg create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/AudioRecording.swift create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/Base.lproj/LaunchScreen.storyboard create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/Base.lproj/Main.storyboard create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/Info.plist create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/SceneDelegate.swift create mode 100644 software/source/clients/ios/zeroone-app/zeroone-app/ViewController.swift diff --git a/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.pbxproj b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.pbxproj new file mode 100644 index 0000000..37a8592 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.pbxproj @@ -0,0 +1,415 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 750E4C0B2BEDD11C00AEE3B1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750E4C0A2BEDD11C00AEE3B1 /* AppDelegate.swift */; }; + 750E4C0D2BEDD11C00AEE3B1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750E4C0C2BEDD11C00AEE3B1 /* SceneDelegate.swift */; }; + 750E4C0F2BEDD11C00AEE3B1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750E4C0E2BEDD11C00AEE3B1 /* ViewController.swift */; }; + 750E4C122BEDD11C00AEE3B1 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 750E4C112BEDD11C00AEE3B1 /* Base */; }; + 750E4C142BEDD11D00AEE3B1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 750E4C132BEDD11D00AEE3B1 /* Assets.xcassets */; }; + 750E4C172BEDD11D00AEE3B1 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 750E4C162BEDD11D00AEE3B1 /* Base */; }; + 750E4C202BEDD16E00AEE3B1 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = 750E4C1F2BEDD16E00AEE3B1 /* Starscream */; }; + 755DC3B22BEE60A7002B66DF /* AudioRecording.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755DC3B12BEE60A7002B66DF /* AudioRecording.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 750E4C072BEDD11C00AEE3B1 /* zeroone-app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "zeroone-app.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 750E4C0A2BEDD11C00AEE3B1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 750E4C0C2BEDD11C00AEE3B1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 750E4C0E2BEDD11C00AEE3B1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 750E4C112BEDD11C00AEE3B1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 750E4C132BEDD11D00AEE3B1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 750E4C162BEDD11D00AEE3B1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 750E4C182BEDD11D00AEE3B1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 755DC3B12BEE60A7002B66DF /* AudioRecording.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRecording.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 750E4C042BEDD11C00AEE3B1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 750E4C202BEDD16E00AEE3B1 /* Starscream in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 750E4BFE2BEDD11C00AEE3B1 = { + isa = PBXGroup; + children = ( + 750E4C092BEDD11C00AEE3B1 /* zeroone-app */, + 750E4C082BEDD11C00AEE3B1 /* Products */, + ); + sourceTree = ""; + }; + 750E4C082BEDD11C00AEE3B1 /* Products */ = { + isa = PBXGroup; + children = ( + 750E4C072BEDD11C00AEE3B1 /* zeroone-app.app */, + ); + name = Products; + sourceTree = ""; + }; + 750E4C092BEDD11C00AEE3B1 /* zeroone-app */ = { + isa = PBXGroup; + children = ( + 750E4C0A2BEDD11C00AEE3B1 /* AppDelegate.swift */, + 750E4C0C2BEDD11C00AEE3B1 /* SceneDelegate.swift */, + 750E4C0E2BEDD11C00AEE3B1 /* ViewController.swift */, + 750E4C102BEDD11C00AEE3B1 /* Main.storyboard */, + 750E4C132BEDD11D00AEE3B1 /* Assets.xcassets */, + 750E4C152BEDD11D00AEE3B1 /* LaunchScreen.storyboard */, + 750E4C182BEDD11D00AEE3B1 /* Info.plist */, + 755DC3B12BEE60A7002B66DF /* AudioRecording.swift */, + ); + path = "zeroone-app"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 750E4C062BEDD11C00AEE3B1 /* zeroone-app */ = { + isa = PBXNativeTarget; + buildConfigurationList = 750E4C1B2BEDD11D00AEE3B1 /* Build configuration list for PBXNativeTarget "zeroone-app" */; + buildPhases = ( + 750E4C032BEDD11C00AEE3B1 /* Sources */, + 750E4C042BEDD11C00AEE3B1 /* Frameworks */, + 750E4C052BEDD11C00AEE3B1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "zeroone-app"; + packageProductDependencies = ( + 750E4C1F2BEDD16E00AEE3B1 /* Starscream */, + ); + productName = "zeroone-app"; + productReference = 750E4C072BEDD11C00AEE3B1 /* zeroone-app.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 750E4BFF2BEDD11C00AEE3B1 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1530; + LastUpgradeCheck = 1530; + TargetAttributes = { + 750E4C062BEDD11C00AEE3B1 = { + CreatedOnToolsVersion = 15.3; + }; + }; + }; + buildConfigurationList = 750E4C022BEDD11C00AEE3B1 /* Build configuration list for PBXProject "zeroone-app" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 750E4BFE2BEDD11C00AEE3B1; + packageReferences = ( + 750E4C1E2BEDD16D00AEE3B1 /* XCRemoteSwiftPackageReference "Starscream" */, + ); + productRefGroup = 750E4C082BEDD11C00AEE3B1 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 750E4C062BEDD11C00AEE3B1 /* zeroone-app */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 750E4C052BEDD11C00AEE3B1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 750E4C142BEDD11D00AEE3B1 /* Assets.xcassets in Resources */, + 750E4C172BEDD11D00AEE3B1 /* Base in Resources */, + 750E4C122BEDD11C00AEE3B1 /* Base in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 750E4C032BEDD11C00AEE3B1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 750E4C0F2BEDD11C00AEE3B1 /* ViewController.swift in Sources */, + 750E4C0B2BEDD11C00AEE3B1 /* AppDelegate.swift in Sources */, + 755DC3B22BEE60A7002B66DF /* AudioRecording.swift in Sources */, + 750E4C0D2BEDD11C00AEE3B1 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 750E4C102BEDD11C00AEE3B1 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 750E4C112BEDD11C00AEE3B1 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 750E4C152BEDD11D00AEE3B1 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 750E4C162BEDD11D00AEE3B1 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 750E4C192BEDD11D00AEE3B1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 15.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 750E4C1A2BEDD11D00AEE3B1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 15.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 750E4C1C2BEDD11D00AEE3B1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 4; + DEVELOPMENT_TEAM = W5NGQJV8X2; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "zeroone-app/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = 01ForiOS; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Audio data from microphone is needed to send commands."; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 15; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.ontheroofstudios.zeroone-app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 750E4C1D2BEDD11D00AEE3B1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 4; + DEVELOPMENT_TEAM = W5NGQJV8X2; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "zeroone-app/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = 01ForiOS; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Audio data from microphone is needed to send commands."; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 15; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.ontheroofstudios.zeroone-app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 750E4C022BEDD11C00AEE3B1 /* Build configuration list for PBXProject "zeroone-app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 750E4C192BEDD11D00AEE3B1 /* Debug */, + 750E4C1A2BEDD11D00AEE3B1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 750E4C1B2BEDD11D00AEE3B1 /* Build configuration list for PBXNativeTarget "zeroone-app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 750E4C1C2BEDD11D00AEE3B1 /* Debug */, + 750E4C1D2BEDD11D00AEE3B1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 750E4C1E2BEDD16D00AEE3B1 /* XCRemoteSwiftPackageReference "Starscream" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/daltoniam/Starscream"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 4.0.8; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 750E4C1F2BEDD16E00AEE3B1 /* Starscream */ = { + isa = XCSwiftPackageProductDependency; + package = 750E4C1E2BEDD16D00AEE3B1 /* XCRemoteSwiftPackageReference "Starscream" */; + productName = Starscream; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 750E4BFF2BEDD11C00AEE3B1 /* Project object */; +} diff --git a/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcuserdata/eladdekel.xcuserdatad/UserInterfaceState.xcuserstate b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/project.xcworkspace/xcuserdata/eladdekel.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..9ad695539a16147d233dc8faf5be5324cff543a9 GIT binary patch literal 69795 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 yI<-2xI=^~ + + + + BuildLocationStyle + UseAppPreferences + CustomBuildLocationType + RelativeToDerivedData + DerivedDataLocationStyle + Default + ShowSharedSchemesAutomaticallyEnabled + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/xcuserdata/eladdekel.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/xcuserdata/eladdekel.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..a1ddc74 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/xcuserdata/eladdekel.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/xcuserdata/eladdekel.xcuserdatad/xcschemes/xcschememanagement.plist b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/xcuserdata/eladdekel.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..31bfb5f --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app.xcodeproj/xcuserdata/eladdekel.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + zeroone-app.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/AppDelegate.swift b/software/source/clients/ios/zeroone-app/zeroone-app/AppDelegate.swift new file mode 100644 index 0000000..de09029 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// zeroone-app +// +// Created by Elad Dekel on 2024-05-09. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return 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. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // 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. + } + + +} + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AccentColor.colorset/Contents.json b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AppIcon.appiconset/Contents.json b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..4e17533 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "O.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AppIcon.appiconset/O.png b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/AppIcon.appiconset/O.png new file mode 100644 index 0000000000000000000000000000000000000000..0e7193ded6a1a14d51fb646fd8f9e584a5ffbf69 GIT binary patch literal 39280 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%0D5cKqEse^Q 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 literal 0 HcmV?d00001 diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/Contents.json b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/vector.imageset/Contents.json b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/vector.imageset/Contents.json new file mode 100644 index 0000000..4311484 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/vector.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "vector.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/vector.imageset/vector.svg b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/vector.imageset/vector.svg new file mode 100644 index 0000000..49c449b --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/Assets.xcassets/vector.imageset/vector.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/AudioRecording.swift b/software/source/clients/ios/zeroone-app/zeroone-app/AudioRecording.swift new file mode 100644 index 0000000..46cde0e --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/AudioRecording.swift @@ -0,0 +1,67 @@ +// +// AudioRecording.swift +// zeroone-app +// +// Created by Elad Dekel on 2024-05-10. +// + +import Foundation +import AVFoundation + +class AudioRecording: NSObject, AVAudioRecorderDelegate { + + var recorder: AVAudioRecorder! + var session: AVAudioSession! + + var isRecording = false + + func startRecording() { + session = AVAudioSession() + let audio = getDocumentsDirectory().appendingPathComponent("tempvoice.wav") // indicates where the audio data will be recording to + let s: [String: Any] = [ + AVFormatIDKey: kAudioFormatLinearPCM, + AVSampleRateKey: 16000.0, + AVNumberOfChannelsKey: 1, + AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue + ] + do { + recorder = try AVAudioRecorder(url: audio, settings: s) + try session.setActive(true) + try session.setCategory(.playAndRecord, mode: .default) + recorder!.delegate = self + recorder!.record() + isRecording = true + + } catch { + print("Error recording") + print(error.localizedDescription) + } + + } + + func getDocumentsDirectory() -> URL { // big thanks to twostraws for this helper function (hackingwithswift.com) + let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) + return paths[0] + } + + + func stopRecording() -> Data? { + if isRecording && recorder != nil { + recorder!.stop() + let audio = getDocumentsDirectory().appendingPathComponent("tempvoice.wav") + recorder = nil + do { + let data = try Data(contentsOf: audio) // sends raw audio data + try FileManager.default.removeItem(at: audio) // deletes the file + return data + } catch { + print(error.localizedDescription) + return nil + } + } else { + print("not recording") + return nil + } + } + +} diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/Base.lproj/LaunchScreen.storyboard b/software/source/clients/ios/zeroone-app/zeroone-app/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/Base.lproj/Main.storyboard b/software/source/clients/ios/zeroone-app/zeroone-app/Base.lproj/Main.storyboard new file mode 100644 index 0000000..d9cd8b2 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/Base.lproj/Main.storyboard @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/Info.plist b/software/source/clients/ios/zeroone-app/zeroone-app/Info.plist new file mode 100644 index 0000000..aef04f9 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/Info.plist @@ -0,0 +1,27 @@ + + + + + NSSpeechRecognitionUsageDescription + Your audio is used the convert your voice requests into text requests. + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/SceneDelegate.swift b/software/source/clients/ios/zeroone-app/zeroone-app/SceneDelegate.swift new file mode 100644 index 0000000..a67a1a3 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// zeroone-app +// +// Created by Elad Dekel on 2024-05-09. +// + +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). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: 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 necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: 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(_ scene: 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(_ scene: 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(_ scene: 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. + } + + +} + diff --git a/software/source/clients/ios/zeroone-app/zeroone-app/ViewController.swift b/software/source/clients/ios/zeroone-app/zeroone-app/ViewController.swift new file mode 100644 index 0000000..0b39175 --- /dev/null +++ b/software/source/clients/ios/zeroone-app/zeroone-app/ViewController.swift @@ -0,0 +1,366 @@ +// +// ViewController.swift +// zeroone-app +// +// Created by Elad Dekel on 2024-05-09. +// + +import UIKit +import Starscream +import AVFoundation + + +class ViewController: UIViewController, WebSocketDelegate { + + @IBOutlet weak var terminalFeed: UITextView! + @IBOutlet weak var terminalButton: UIImageView! + @IBOutlet weak var reconnectIcon: UIImageView! + @IBOutlet weak var circle: UIImageView! + @IBOutlet weak var settingsGear: UIImageView! + @IBOutlet weak var infoText: UILabel! + + var audioRecordingInstance: AudioRecording? + private var audioData = Data() + private var audioPlayer: AVAudioPlayer? + var address: String? + var isConnected = false + var recordingPermission = false + var terminal = false + var socket: WebSocket? + + + override func viewDidLoad() { + super.viewDidLoad() + terminalFeed.layer.cornerRadius = 15 + infoText.text = "Hold to start once connected." + // Create a gesture recognizer that tracks when the "button" is held + let pressGesture = UILongPressGestureRecognizer(target: self, action: #selector(buttonPress(_:))) + pressGesture.minimumPressDuration = 0.01 + circle.addGestureRecognizer(pressGesture) + circle.isUserInteractionEnabled = true + circle.translatesAutoresizingMaskIntoConstraints = false + + // Create a geature recognizer for the settings button + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(settingsGear(_:))) + settingsGear.addGestureRecognizer(tapGesture) + settingsGear.isUserInteractionEnabled = true + + + let reconnectGesture = UITapGestureRecognizer(target: self, action: #selector(recconectIcon(_:))) + reconnectIcon.addGestureRecognizer(reconnectGesture) + reconnectIcon.isUserInteractionEnabled = true + + + let terminal = UITapGestureRecognizer(target: self, action: #selector(terminalIcon(_:))) + terminalButton.addGestureRecognizer(terminal) + terminalButton.isUserInteractionEnabled = true + + + } + + + + + + + func checkRecordingPerms() { + let sess = AVAudioSession.sharedInstance() + switch (sess.recordPermission) { + case.denied, .undetermined: + sess.requestRecordPermission { (granted) in + if granted { + self.recordingPermission = true + } else { + let alert = UIAlertController(title: "Recording Not Permitted", message: "You must allow audio recording in order to send commands. Close the app and re-open it to try again.", preferredStyle: .alert) + let action = UIAlertAction(title: "Understood", style: .default) + alert.addAction(action) + self.present(alert, animated: true) + } + } + case .granted: + recordingPermission = true + default: + break + } + } + + override func viewDidAppear(_ animated: Bool) { + if ((UserDefaults.standard.value(forKey: "IPINFO")) != nil) { + print("here") + address = UserDefaults.standard.string(forKey: "IPINFO") + establishConnection() + } else { + print("there") + setAddress() + } + checkRecordingPerms() + } + + func receieved(data: String) { + infoText.text = data + } + + + + + + func setAddress() { + let alert = UIAlertController(title: "Set the Address", message: "Input the address of the WebSocket (found in the terminal running 01 software)", preferredStyle: .alert) + alert.addTextField { (field) in + field.placeholder = "Enter Address Here" + } + let cancelButton = UIAlertAction(title: "Cancel", style: .cancel) + alert.addAction(cancelButton) + let submitButton = UIAlertAction(title: "Done", style: .default) { (_) in + if let field = alert.textFields?.first, let text = field.text { + UserDefaults.standard.setValue(text, forKey: "IPINFO") + self.address = text + self.establishConnection() + // HAVE THE TEXT FIELD + } + } + alert.addAction(submitButton) + + present(alert, animated: true) + } + + @objc func recconectIcon(_ sender: UIGestureRecognizer) { + infoText.text = "" + self.establishConnection() + } + + @objc func terminalIcon(_ sender: UIGestureRecognizer) { + if (terminal) { + UIView.animate(withDuration: 0.3) { + self.terminalFeed.text = "" + self.terminalFeed.alpha = 0 + let moveT = CGAffineTransform(translationX: 0, y: -190) + self.appendTranslation(transform: moveT) + self.terminalButton.image = UIImage(systemName: "apple.terminal") + } completion: { done in + self.terminal = false + } + } else { + UIView.animate(withDuration: 0.3) { + self.terminalFeed.alpha = 1 + let moveT = CGAffineTransform(translationX: 0, y: 190) + self.appendTranslation(transform: moveT) + self.terminalButton.image = UIImage(systemName: "apple.terminal.fill") + } completion: { done in + self.terminal = true + } + + } + } + + @objc func settingsGear(_ sender: UIGestureRecognizer) { + infoText.text = "" + setAddress() + } + + func appendTranslation(transform: CGAffineTransform) { + var currentTransform = self.circle.transform + currentTransform = currentTransform.concatenating(transform) + self.circle.transform = currentTransform + } + + @objc func buttonPress(_ sender: UILongPressGestureRecognizer) { + infoText.text = "" + let feedback = UIImpactFeedbackGenerator(style: .medium) + if sender.state == .began { + socket?.connect() + // check for recording permission, if exists + // it began, start recording! + if (isConnected && recordingPermission) { + audioRecordingInstance = AudioRecording() + audioRecordingInstance!.startRecording() + infoText.text = "" + UIView.animate(withDuration: 0.1) { + self.circle.tintColor = .green + let newT = CGAffineTransform(scaleX: 0.7, y: 0.7) + self.appendTranslation(transform: newT) + feedback.prepare() + feedback.impactOccurred() + } + } else { + let errorFeedback = UIImpactFeedbackGenerator(style: .heavy) + errorFeedback.prepare() + errorFeedback.impactOccurred() + if (isConnected && !recordingPermission) { + infoText.text = "Not recording permission. Please close and re-open the app." + } else { + infoText.text = "Not connected." + establishConnection() + } + UIView.animate(withDuration: 0.5) { + self.circle.tintColor = .red + } completion: { _ in + self.circle.tintColor = .systemYellow + } + + + } + } else if sender.state == .ended { + if (isConnected && recordingPermission) { + if (audioRecordingInstance != nil) { + let response = audioRecordingInstance!.stopRecording() + if (response != nil) { + sendAudio(audio: response!) + } + UIView.animate(withDuration: 0.1) { + self.circle.tintColor = .systemYellow + let newT = CGAffineTransform(scaleX: 1.4, y: 1.4) + self.appendTranslation(transform: newT) + feedback.prepare() + feedback.impactOccurred() + } + } + } + // stop recording and send the audio + } + } + + + + + + func establishConnection() { //connect to the web socket + if (address != nil) { + var request = URLRequest(url: URL(string: "http://\(address!)")!) + request.timeoutInterval = 5 + socket = WebSocket(request: request) + socket!.delegate = self + socket!.connect() + } else { + setAddress() + } + } + + func didReceive(event: Starscream.WebSocketEvent, client: any Starscream.WebSocketClient) { // deal with receiving data from websocket + switch event { + case .connected( _): + isConnected = true + reconnectIcon.tintColor = .green + case .disconnected(let reason, let code): + isConnected = false + reconnectIcon.tintColor = .red + case .text(let string): + if (terminal) { + terminalFeed.text = terminalFeed.text + "\n>> \(string)" + let range = NSMakeRange(terminalFeed.text.count - 1, 0) + terminalFeed.scrollRangeToVisible(range) + } + if (string.contains("audio") && string.contains("bytes.raw") && string.contains("start")) { + infoText.text = "Receiving response..." + // it started collecting data! + print("Audio is being receieved.") + } else if (string.contains("audio") && string.contains("bytes.raw") && string.contains("end")) { + infoText.text = "" + print("Audio is no longer being receieved.") + let wavHeader = createWAVHeader(audioDataSize: Int32(audioData.count - 44)) + // Combine header and data + var completeWAVData = Data() + completeWAVData.append(wavHeader) + completeWAVData.append(audioData.subdata(in: 44.. Data { + let headerSize: Int32 = 44 // Standard WAV header size + let chunkSize: Int32 = 36 + audioDataSize + let sampleRate: Int32 = 16000 // From i2s_config + let numChannels: Int16 = 1 // From i2s_config (mono) + let bitsPerSample: Int16 = 16 // From i2s_config + let byteRate: Int32 = sampleRate * Int32(numChannels) * Int32(bitsPerSample) / 8 + let blockAlign: Int16 = numChannels * bitsPerSample / 8 + + var headerData = Data() + + // RIFF Chunk + headerData.append(stringToData("RIFF")) // ChunkID + headerData.append(int32ToData(chunkSize)) // ChunkSize + headerData.append(stringToData("WAVE")) // Format + + // fmt Subchunk + headerData.append(stringToData("fmt ")) // Subchunk1ID + headerData.append(int32ToData(16)) // Subchunk1Size (16 for PCM) + headerData.append(int16ToData(1)) // AudioFormat (1 for PCM) + headerData.append(int16ToData(numChannels)) // NumChannels + headerData.append(int32ToData(sampleRate)) // SampleRate + headerData.append(int32ToData(byteRate)) // ByteRate + headerData.append(int16ToData(blockAlign)) // BlockAlign + headerData.append(int16ToData(bitsPerSample)) // BitsPerSample + + // data Subchunk + headerData.append(stringToData("data")) // Subchunk2ID + headerData.append(int32ToData(audioDataSize)) // Subchunk2Size + + return headerData + } + + func stringToData(_ string: String) -> Data { + return string.data(using: .utf8)! + } + + func int16ToData(_ value: Int16) -> Data { + var value = value.littleEndian + return Data(bytes: &value, count: MemoryLayout.size) + } + + func int32ToData(_ value: Int32) -> Data { + var value = value.littleEndian + return Data(bytes: &value, count: MemoryLayout.size) + } + + + func sendAudio(audio: Data) { + if (isConnected) { + socket!.write(string: "{\"role\": \"user\", \"type\": \"audio\", \"format\": \"bytes.raw\", \"start\": true}") + socket!.write(data: audio) + socket!.write(string: "{\"role\": \"user\", \"type\": \"audio\", \"format\": \"bytes.raw\", \"end\": true}") + } else { + print("Not connected!") + } + } + + + + + +} + +