From 2815facc494af93b0fe49ff999cf967663332de0 Mon Sep 17 00:00:00 2001 From: Dominic Hawken Date: Mon, 16 Mar 2020 00:45:52 +0000 Subject: [PATCH 1/4] Typo in baud rate settings (#154) --- Source/ORSSerialPort.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ORSSerialPort.h b/Source/ORSSerialPort.h index adf2e773..3136018a 100644 --- a/Source/ORSSerialPort.h +++ b/Source/ORSSerialPort.h @@ -416,7 +416,7 @@ NS_ASSUME_NONNULL_BEGIN /** * The baud rate for the port. * - * Unless supportsNonStandardBaudRates is YES, + * Unless allowsNonStandardBaudRates is YES, * this value should be one of the values defined in termios.h: * * - 0 From b088352a70fe83431de965f63522d2f0c45a3dcc Mon Sep 17 00:00:00 2001 From: Andrew Madsen Date: Tue, 30 Jun 2020 00:37:19 -0600 Subject: [PATCH 2/4] Update to latest recommended project settings (Xcode 12) --- .../ORSSerialPort.xcodeproj/project.pbxproj | 4 +++- .../xcshareddata/xcschemes/ORSSerial.xcscheme | 15 +-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/Framework Project/ORSSerialPort.xcodeproj/project.pbxproj b/Framework Project/ORSSerialPort.xcodeproj/project.pbxproj index b50418f6..c829d23b 100644 --- a/Framework Project/ORSSerialPort.xcodeproj/project.pbxproj +++ b/Framework Project/ORSSerialPort.xcodeproj/project.pbxproj @@ -221,7 +221,7 @@ 9DCA89091A2BB106009285EB /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Open Reel Software"; TargetAttributes = { 9D7472121B6D7767002D8B10 = { @@ -362,6 +362,7 @@ 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; @@ -418,6 +419,7 @@ 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; diff --git a/Framework Project/ORSSerialPort.xcodeproj/xcshareddata/xcschemes/ORSSerial.xcscheme b/Framework Project/ORSSerialPort.xcodeproj/xcshareddata/xcschemes/ORSSerial.xcscheme index 326ae0cb..8ea7f863 100644 --- a/Framework Project/ORSSerialPort.xcodeproj/xcshareddata/xcschemes/ORSSerial.xcscheme +++ b/Framework Project/ORSSerialPort.xcodeproj/xcshareddata/xcschemes/ORSSerial.xcscheme @@ -1,6 +1,6 @@ - - - - - - - - Date: Wed, 1 Jul 2020 14:01:34 -0600 Subject: [PATCH 3/4] Update to latest recommended project settings (Xcode 12.0 beta 1) --- Source/ORSSerialRequest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ORSSerialRequest.h b/Source/ORSSerialRequest.h index 9cbe4d1a..8cfa086b 100644 --- a/Source/ORSSerialRequest.h +++ b/Source/ORSSerialRequest.h @@ -25,7 +25,7 @@ // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import -#import "ORSSerialPacketDescriptor.h" +#import // Keep older versions of the compiler happy #ifndef NS_ASSUME_NONNULL_BEGIN From 24ec6a166178d0f4484ebcfc292588f5beca25fe Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 2 Oct 2020 18:26:28 +0200 Subject: [PATCH 4/4] Add ORSSerialSwiftUIDemo An example how one can implement ORSSerialPort in SwiftUI. --- Examples/ORSSerialSwiftUIDemo/README.md | 3 + .../SwiftUIDemo.xcodeproj/project.pbxproj | 396 ++++++++++ .../SwiftUIDemo/SwiftUIDemo/AppDelegate.swift | 39 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 58 ++ .../SwiftUIDemo/Assets.xcassets/Contents.json | 6 + .../SwiftUIDemo/Base.lproj/Main.storyboard | 683 ++++++++++++++++++ .../SwiftUIDemo/SwiftUIDemo/ContentView.swift | 22 + .../SwiftUIDemo/Demo/DemoView.swift | 311 ++++++++ .../SwiftUIDemo/Demo/SerialPortCombine.swift | 300 ++++++++ .../SwiftUIDemo/Demo/ViewModel.swift | 116 +++ .../Swift/SwiftUIDemo/SwiftUIDemo/Info.plist | 30 + .../Preview Assets.xcassets/Contents.json | 6 + .../SwiftUIDemo/SwiftUIDemo.entitlements | 14 + 14 files changed, 1995 insertions(+) create mode 100644 Examples/ORSSerialSwiftUIDemo/README.md create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/AppDelegate.swift create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Contents.json create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Base.lproj/Main.storyboard create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/ContentView.swift create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/DemoView.swift create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/SerialPortCombine.swift create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/ViewModel.swift create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Info.plist create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/SwiftUIDemo.entitlements diff --git a/Examples/ORSSerialSwiftUIDemo/README.md b/Examples/ORSSerialSwiftUIDemo/README.md new file mode 100644 index 00000000..2f7ce6d7 --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/README.md @@ -0,0 +1,3 @@ +SwiftUIDemo + +The ORSSerialPortDemo written in SwiftUI. diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj new file mode 100644 index 00000000..2404656f --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj @@ -0,0 +1,396 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 52; + objects = { + +/* Begin PBXBuildFile section */ + A3B14AFB2527442700D44E89 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3B14AFA2527442700D44E89 /* AppDelegate.swift */; }; + A3B14AFD2527442700D44E89 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3B14AFC2527442700D44E89 /* ContentView.swift */; }; + A3B14AFF2527442800D44E89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A3B14AFE2527442800D44E89 /* Assets.xcassets */; }; + A3B14B022527442800D44E89 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A3B14B012527442800D44E89 /* Preview Assets.xcassets */; }; + A3B14B052527442800D44E89 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A3B14B032527442800D44E89 /* Main.storyboard */; }; + A3B14B13252744BE00D44E89 /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3B14B0F252744BE00D44E89 /* ViewModel.swift */; }; + A3B14B14252744BE00D44E89 /* DemoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3B14B10252744BE00D44E89 /* DemoView.swift */; }; + A3B14B16252744BE00D44E89 /* SerialPortCombine.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3B14B12252744BE00D44E89 /* SerialPortCombine.swift */; }; + A3B14B1B2527456D00D44E89 /* ORSSerial in Frameworks */ = {isa = PBXBuildFile; productRef = A3B14B1A2527456D00D44E89 /* ORSSerial */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + A3B14AF72527442700D44E89 /* SwiftUIDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUIDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + A3B14AFA2527442700D44E89 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + A3B14AFC2527442700D44E89 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + A3B14AFE2527442800D44E89 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + A3B14B012527442800D44E89 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + A3B14B042527442800D44E89 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + A3B14B062527442800D44E89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A3B14B072527442800D44E89 /* SwiftUIDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SwiftUIDemo.entitlements; sourceTree = ""; }; + A3B14B0F252744BE00D44E89 /* ViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = ""; }; + A3B14B10252744BE00D44E89 /* DemoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoView.swift; sourceTree = ""; }; + A3B14B12252744BE00D44E89 /* SerialPortCombine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerialPortCombine.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + A3B14AF42527442700D44E89 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A3B14B1B2527456D00D44E89 /* ORSSerial in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + A3B14AEE2527442700D44E89 = { + isa = PBXGroup; + children = ( + A3B14AF92527442700D44E89 /* SwiftUIDemo */, + A3B14AF82527442700D44E89 /* Products */, + ); + sourceTree = ""; + }; + A3B14AF82527442700D44E89 /* Products */ = { + isa = PBXGroup; + children = ( + A3B14AF72527442700D44E89 /* SwiftUIDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + A3B14AF92527442700D44E89 /* SwiftUIDemo */ = { + isa = PBXGroup; + children = ( + A3B14B0E2527449E00D44E89 /* Demo */, + A3B14AFA2527442700D44E89 /* AppDelegate.swift */, + A3B14AFC2527442700D44E89 /* ContentView.swift */, + A3B14AFE2527442800D44E89 /* Assets.xcassets */, + A3B14B032527442800D44E89 /* Main.storyboard */, + A3B14B062527442800D44E89 /* Info.plist */, + A3B14B072527442800D44E89 /* SwiftUIDemo.entitlements */, + A3B14B002527442800D44E89 /* Preview Content */, + ); + path = SwiftUIDemo; + sourceTree = ""; + }; + A3B14B002527442800D44E89 /* Preview Content */ = { + isa = PBXGroup; + children = ( + A3B14B012527442800D44E89 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + A3B14B0E2527449E00D44E89 /* Demo */ = { + isa = PBXGroup; + children = ( + A3B14B10252744BE00D44E89 /* DemoView.swift */, + A3B14B0F252744BE00D44E89 /* ViewModel.swift */, + A3B14B12252744BE00D44E89 /* SerialPortCombine.swift */, + ); + path = Demo; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + A3B14AF62527442700D44E89 /* SwiftUIDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = A3B14B0A2527442800D44E89 /* Build configuration list for PBXNativeTarget "SwiftUIDemo" */; + buildPhases = ( + A3B14AF32527442700D44E89 /* Sources */, + A3B14AF42527442700D44E89 /* Frameworks */, + A3B14AF52527442700D44E89 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftUIDemo; + packageProductDependencies = ( + A3B14B1A2527456D00D44E89 /* ORSSerial */, + ); + productName = SwiftUIDemo; + productReference = A3B14AF72527442700D44E89 /* SwiftUIDemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + A3B14AEF2527442700D44E89 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1200; + LastUpgradeCheck = 1200; + TargetAttributes = { + A3B14AF62527442700D44E89 = { + CreatedOnToolsVersion = 12.0.1; + }; + }; + }; + buildConfigurationList = A3B14AF22527442700D44E89 /* Build configuration list for PBXProject "SwiftUIDemo" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = A3B14AEE2527442700D44E89; + packageReferences = ( + A3B14B192527456D00D44E89 /* XCRemoteSwiftPackageReference "ORSSerialPort" */, + ); + productRefGroup = A3B14AF82527442700D44E89 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A3B14AF62527442700D44E89 /* SwiftUIDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + A3B14AF52527442700D44E89 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A3B14B052527442800D44E89 /* Main.storyboard in Resources */, + A3B14B022527442800D44E89 /* Preview Assets.xcassets in Resources */, + A3B14AFF2527442800D44E89 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + A3B14AF32527442700D44E89 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A3B14B16252744BE00D44E89 /* SerialPortCombine.swift in Sources */, + A3B14B14252744BE00D44E89 /* DemoView.swift in Sources */, + A3B14AFD2527442700D44E89 /* ContentView.swift in Sources */, + A3B14B13252744BE00D44E89 /* ViewModel.swift in Sources */, + A3B14AFB2527442700D44E89 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + A3B14B032527442800D44E89 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A3B14B042527442800D44E89 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + A3B14B082527442800D44E89 /* 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; + 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; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + A3B14B092527442800D44E89 /* 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; + 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; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + A3B14B0B2527442800D44E89 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = SwiftUIDemo/SwiftUIDemo.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_ASSET_PATHS = "\"SwiftUIDemo/Preview Content\""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUIDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.15; + PRODUCT_BUNDLE_IDENTIFIER = com.ORSSerial.SwiftUIDemo.SwiftUIDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + A3B14B0C2527442800D44E89 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = SwiftUIDemo/SwiftUIDemo.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_ASSET_PATHS = "\"SwiftUIDemo/Preview Content\""; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = SwiftUIDemo/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.15; + PRODUCT_BUNDLE_IDENTIFIER = com.ORSSerial.SwiftUIDemo.SwiftUIDemo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A3B14AF22527442700D44E89 /* Build configuration list for PBXProject "SwiftUIDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A3B14B082527442800D44E89 /* Debug */, + A3B14B092527442800D44E89 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A3B14B0A2527442800D44E89 /* Build configuration list for PBXNativeTarget "SwiftUIDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A3B14B0B2527442800D44E89 /* Debug */, + A3B14B0C2527442800D44E89 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + A3B14B192527456D00D44E89 /* XCRemoteSwiftPackageReference "ORSSerialPort" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/armadsen/ORSSerialPort.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.1.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + A3B14B1A2527456D00D44E89 /* ORSSerial */ = { + isa = XCSwiftPackageProductDependency; + package = A3B14B192527456D00D44E89 /* XCRemoteSwiftPackageReference "ORSSerialPort" */; + productName = ORSSerial; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = A3B14AEF2527442700D44E89 /* Project object */; +} diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/AppDelegate.swift b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/AppDelegate.swift new file mode 100644 index 00000000..b34d4fcd --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/AppDelegate.swift @@ -0,0 +1,39 @@ +// +// AppDelegate.swift +// SwiftUIDemo +// +// Created by Jan Anstipp on 02.10.20. +// + +import Cocoa +import SwiftUI + +@NSApplicationMain +class AppDelegate: NSObject, NSApplicationDelegate { + + var window: NSWindow! + + + func applicationDidFinishLaunching(_ aNotification: Notification) { + // Create the SwiftUI view that provides the window contents. + let contentView = ContentView() + + // Create the window and set the content view. + window = NSWindow( + contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), + styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], + backing: .buffered, defer: false) + window.isReleasedWhenClosed = false + window.center() + window.setFrameAutosaveName("Main Window") + window.contentView = NSHostingView(rootView: contentView) + window.makeKeyAndOrderFront(nil) + } + + func applicationWillTerminate(_ aNotification: Notification) { + // Insert code here to tear down your application + } + + +} + diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AccentColor.colorset/Contents.json b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..3f00db43 --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Contents.json b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Base.lproj/Main.storyboard b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Base.lproj/Main.storyboard new file mode 100644 index 00000000..7cedc66a --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Base.lproj/Main.storyboard @@ -0,0 +1,683 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/ContentView.swift b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/ContentView.swift new file mode 100644 index 00000000..36775c53 --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/ContentView.swift @@ -0,0 +1,22 @@ +// +// ContentView.swift +// SwiftUIDemo +// +// Created by Jan Anstipp on 02.10.20. +// + +import SwiftUI + +struct ContentView: View { + @ObservedObject var viewM: ViewModel = ViewModel() + var body: some View { + DemoView(viewM: viewM) + } +} + + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/DemoView.swift b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/DemoView.swift new file mode 100644 index 00000000..39d4946e --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/DemoView.swift @@ -0,0 +1,311 @@ +// +// SerialPortSettingView.swift +// SerialPort +// +// Created by Jan Anstipp on 30.09.20. +// + +import SwiftUI +import ORSSerial + +struct DemoView: View{ + @ObservedObject var viewM: ViewModel + var debug: Bool = false + var body: some View{ + HStack{ + VStack{ + HStack{ + Text("Port") + Picker("", selection: $viewM.path){ + ForEach(viewM.availablePorts , id: \.self) { + Text($0) + } + }.frame(width: 200) + } + .padding(.trailing, 8) + .padding(.leading, 70) + + if let serialPort = viewM.serialPort{ + PortSettingView(viewM: viewM, serialP: serialPort) + } + + }.frame(minWidth: 500, maxWidth: .infinity, minHeight: 800, idealHeight: 800, maxHeight: .infinity, alignment: .center) + //Debuggin + if debug{ + SettingsView(settings: $viewM.settings) + SettingsView(settings: $viewM.settingsDebug) + Button("Update", action: { self.viewM.updatePortTestSetting()}) + } + } + } +} + +struct PortSettingView: View{ + @ObservedObject var viewM: ViewModel + @ObservedObject var serialP: ORSSerialPortCombine + + @State private var isAdd: Bool = false + @State private var suffix: Suffix = .none + @State private var command: String = "" + var body: some View { + VStack{ + //====== Port Settings ====== + VStack{ + HStack(alignment: .top){ + VStack(alignment: .trailing ){ + Text("Bautrate") + Text("StopBits").padding([.top], 14) + Text("Parity").padding([.top], 14) + } + VStack(alignment: .leading){ + Picker("", selection: $serialP.baudRate){ + ForEach(BaudRate.allCases, id: \.value) { + Text(String($0.value)) + } + } + Picker("", selection: $serialP.numberOfStopBits){ + ForEach([1,2], id: \.self) { + Text(String($0)) + } + } + .frame(width: 70) + .pickerStyle(SegmentedPickerStyle()) + + Picker("", selection: $serialP.parity){ + ForEach(ORSSerialPortParity.allCases(), id: \.self) { + Text($0.description()) + } + } + .frame(width: 160) + .pickerStyle(SegmentedPickerStyle()) + }.frame(width: 200) + Button(viewM.settings.isOpen ? "Close" : "Open") { viewM.settings.isOpen ? serialP.close() : serialP.open() } + } + } + .alignmentGuide( HorizontalAlignment.center, computeValue: { d in + return ( d[HorizontalAlignment.center] - 50) + }) + + //====== Intput Output ====== + Divider() + VStack{ + Text("Input OutPut") + .alignmentGuide(HorizontalAlignment.center, computeValue: { dimension in + dimension[HorizontalAlignment.center] - 55 + }) + HStack(alignment: .top){ + Text("Flow Controll") + + VStack(alignment:.leading){ + Toggle("RTS/CTS", isOn: $serialP.usesRTSCTSFlowControl).padding([.top,.bottom], 1) + Toggle("DTR/DSR", isOn: $serialP.usesDTRDSRFlowControl).padding([.top,.bottom], 1) + Toggle("DCD", isOn: $serialP.usesDCDOutputFlowControl).padding([.top,.bottom], 1) + Toggle("Echo", isOn: $serialP.shouldEchoReceivedData).padding([.top,.bottom], 1) + } + } + + } + .alignmentGuide( HorizontalAlignment.center, computeValue: { d in + return ( d[HorizontalAlignment.center] + 45) + }) + + + //====== Terminal ====== + Divider() + + HStack{ + TextField("", text: $command ) + Button("Send", action: { serialP.send(value: command, suffix: (isAdd ? suffix.value : "")) }) + Toggle(isOn: $isAdd , label: { Text("Add") }) + + Picker("", selection: $suffix){ + ForEach(Suffix.allCases, id: \.self) { x in + Text(x.description) + } + }.frame(width: 110) + }.padding() + + Divider() + VStack(alignment: .leading){ + Button("Clear", action: { + + }) + ScrollView{ + TextField("", text: $viewM.recieve ) + .multilineTextAlignment(.leading) + } + + } + .frame(minHeight: 200, idealHeight: 300, maxHeight: .infinity) + .padding() + + //====== Output Input ====== + + HStack{ + Text("PinState").padding(.top, 25) + .padding([.leading,.trailing], 10) + VStack{ + Text("Output") + HStack{ + Toggle("RTS", isOn: $serialP.rts) + Toggle("DTR", isOn: $serialP.dtr) + } + + }.padding([.leading,.trailing], 20) + VStack{ + Text("Input") + HStack{ + Toggle("CTS", isOn: $viewM.settings.cts).disabled(true) + Toggle("DSR", isOn: $viewM.settings.dsr).disabled(true) + Toggle("DCD", isOn: $viewM.settings.dcdIn).disabled(true) + } + }.padding([.leading,.trailing], 20) + }.frame(width: 500) + + //====== fooder ====== + Divider() + HStack{ + Spacer() + Text(viewM.settings.name) + Text("Baudrate: "+String(serialP.baudRate)) + Text(viewM.settings.isConnect ? "Device: Connect" : "Device: Disconect") + Text(viewM.settings.isOpen ? "Port: Open" : "Port: Close") + + } + + } + } +} + +struct SettingsView: View { + @Binding var settings: PortSettings + var body: some View{ + + HStack{ + + VStack(alignment: .trailing){ + Text("path") + Text("name") + Text("baudRate") + Text("Stopbits") + Text("parity") + Text("rts/cts") + Group{ + Text("dtr/dsr") + Text("dcd") + Text("echo") + Text("rts") + Text("dtr") + Text("cts") + Text("dsr") + Text("dcd") + Text("port") + Text("device") + } + } + VStack(alignment: .leading){ + Text(settings.path) + Text(settings.name) + Text(settings.baudRate.description) + Text(String(settings.numberOfStopBits)) + Text(settings.parity.description()) + Text(settings.usesRTSCTSFlowControl ? "on" : "off") + Group{ + Text(settings.usesDTRDSRFlowControl ? "on" : "off") + Text(settings.usesDCDOutputFlowControl ? "on" : "off") + Text(settings.echo ? "on" : "off") + Text(settings.rts ? "on" : "off") + Text(settings.dtr ? "on" : "off") + Text(settings.cts ? "on" : "off") + Text(settings.dsr ? "on" : "off") + Text(settings.dcdIn ? "on" : "off") + Text(settings.isOpen ? "open" : "close") + Text(settings.isConnect ? "connect" : "disconnect") + } + } + } + + } +} + + +struct PortSelectionView_Previews: PreviewProvider { + static let viewM = ViewModel() + static var previews: some View { + DemoView(viewM: viewM) + } +} + +struct SettingView_Previews: PreviewProvider { + @State static var port = PortSettings() + static var previews: some View { + SettingsView(settings: $port) + .frame(width: 300, height: 300, alignment: .center) + } +} + +//You need change the URL if you will see this Preview. +struct PortSettingView_Previews: PreviewProvider { + static let viewM = ViewModel() + static let port = ORSSerialPortCombine("/dev/cu.usbmodem143201")! + + static var previews: some View { + PortSettingView(viewM: viewM, serialP: port) + } +} + +enum Suffix: CaseIterable{ + case cr + case lf + case crls + case none + + var description: String { + switch self { + case .cr: return "CR (\\r}" + case .lf: return "LF (\\n)" + case .crls: return "CRLF (\\r\\n)" + case .none: return "none" + } + } + var value: String { + switch self { + case .cr: return "\r" + case .lf: return "\n" + case .crls: return "\r\n)" + case .none: return "" + } + } +} + +enum BaudRate: CaseIterable{ + case _300 + case _1200 + case _2400 + case _4800 + case _9600 + case _14400 + case _19200 + case _28800 + case _38400 + case _57600 + case _115200 + case _230400 + + var value: Int{ + switch(self){ + case ._300: return 300 + case ._1200: return 1200 + case ._2400: return 2400 + case ._4800: return 4800 + case ._9600: return 9600 + case ._14400: return 14400 + case ._19200: return 19200 + case ._28800: return 28800 + case ._38400: return 38400 + case ._57600: return 57600 + case ._115200: return 115200 + case ._230400: return 230400 + } + } +} diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/SerialPortCombine.swift b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/SerialPortCombine.swift new file mode 100644 index 00000000..6b0ae9ae --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/SerialPortCombine.swift @@ -0,0 +1,300 @@ +// +// SerialPort.swift +// SerialPort +// +// Created by Jan Anstipp on 30.09.20. +// + +import Foundation +import ORSSerial +import Combine + + +class ORSSerialPortCombine:NSObject, ObservableObject { + + @Published var baudRate: Int + @Published var allowsNonStandardBaudRates: Bool + @Published var numberOfStopBits: Int + @Published var parity: ORSSerialPortParity + @Published var usesRTSCTSFlowControl: Bool + @Published var usesDTRDSRFlowControl: Bool + @Published var usesDCDOutputFlowControl: Bool + @Published var shouldEchoReceivedData: Bool + @Published var rts: Bool + @Published var dtr: Bool + @Published var numberOfDataBits: Int + + var receiveDataSub: AnyPublisher { receiveData.eraseToAnyPublisher() } + var receivePacketSub: AnyPublisher<(data: Data,description:ORSSerialPacketDescriptor),Never> { receivePacket.eraseToAnyPublisher() } + var errorSub: AnyPublisher { error.eraseToAnyPublisher() } + var responseDataSub: AnyPublisher<(data:Data,request:ORSSerialRequest),Never> { responseData.eraseToAnyPublisher() } + var requestTimeoutSub: AnyPublisher { requestTimeout.eraseToAnyPublisher() } + var portSettingsSub: AnyPublisher { portSettings.eraseToAnyPublisher() } + + private var isConnect: CurrentValueSubject + private var isOpen: CurrentValueSubject + private var receiveData = PassthroughSubject() + private var receivePacket = PassthroughSubject<(data:Data,description:ORSSerialPacketDescriptor),Never>() + private var error = PassthroughSubject() + private var responseData = PassthroughSubject<(data:Data,request:ORSSerialRequest),Never>() + private var requestTimeout = PassthroughSubject() + private var portSettings: CurrentValueSubject + + // pendingRequest, queuedRequests we need CurrentValueSubject or PassthroughSubject? + // var pendingRequest: CurrentValueSubject + // var queuedRequests: CurrentValueSubject + + var name: String { port.name } + var path: String { port.path } + + var packetDescriptors: [ORSSerialPacketDescriptor] { port.packetDescriptors } + // cant use it in swift + // var ioKitDevice: IOKitDevice { port.ioKitDevice } + + //is private only for debuggin public + let port: ORSSerialPort + private var subSet = Set() + + func open(){ port.open() } + func close(){ port.close() } + + func send(value:String, suffix: String){ + var data = value + if !data.hasSuffix("\n") { + data += suffix + } + if let data = data.data(using: .utf8) { + port.send(data) + } + } + + init?(_ path: String){ + guard let newPort = ORSSerialPort(path: path) else { return nil } + port = newPort + + baudRate = Int(truncating: port.baudRate) + numberOfStopBits = Int(port.numberOfStopBits) + parity = port.parity + usesRTSCTSFlowControl = port.usesRTSCTSFlowControl + usesDTRDSRFlowControl = port.usesDTRDSRFlowControl + usesDCDOutputFlowControl = port.usesDCDOutputFlowControl + shouldEchoReceivedData = port.shouldEchoReceivedData + rts = port.rts + dtr = port.dtr + numberOfDataBits = Int(port.numberOfDataBits) + isConnect = .init(true) + isOpen = .init(port.isOpen) + allowsNonStandardBaudRates = port.allowsNonStandardBaudRates + portSettings = .init(PortSettings(port, isConnect: false)) + + super.init() + port.delegate = self + initPublisherSub() + initKVOSub() + initNotificationSub() + } + + deinit { + port.delegate = nil + } + + func initPublisherSub(){ + $baudRate + .removeDuplicates() + .sink{value in + self.port.baudRate = NSNumber(value: value) + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + $numberOfStopBits + .removeDuplicates() + .map{UInt($0)} + .sink{value in + self.port.numberOfStopBits = value + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + $parity + .removeDuplicates() + .sink{value in + self.port.parity = value + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + $usesRTSCTSFlowControl + .removeDuplicates() + .sink{value in + self.port.usesRTSCTSFlowControl = value + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + $usesDTRDSRFlowControl + .removeDuplicates() + .sink{value in + self.port.usesDTRDSRFlowControl = value + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + $usesDCDOutputFlowControl + .removeDuplicates() + .sink{value in + self.port.usesDCDOutputFlowControl = value + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + $shouldEchoReceivedData + .removeDuplicates() + .sink{value in + self.port.shouldEchoReceivedData = value + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + $rts + .removeDuplicates() + .sink{value in + self.port.rts = value + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + $dtr + .removeDuplicates() + .sink{value in + self.port.dtr = value + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + $numberOfDataBits + .removeDuplicates() + .map{UInt($0)} + .sink{value in + self.port.numberOfDataBits = value + self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + + $allowsNonStandardBaudRates + .removeDuplicates() + .sink{ value in + self.port.allowsNonStandardBaudRates = value + self.portSettings.send(PortSettings(self.port,isConnect: self.isConnect.value))} + .store(in: &subSet) + + + } + + func initNotificationSub(){ + isConnect + .removeDuplicates() + .sink{ self.portSettings.send(PortSettings(self.port, isConnect: $0)) } + .store(in: &subSet) + + isOpen + .removeDuplicates() + .sink{_ in self.portSettings.send(PortSettings(self.port, isConnect: self.isConnect.value)) } + .store(in: &subSet) + + NotificationCenter.default + .publisher(for: NSNotification.Name.ORSSerialPortsWereConnected) + .sink() { notification in + if let userInfo = notification.userInfo { + let connectedPorts = userInfo[ORSConnectedSerialPortsKey] as! [ORSSerialPort] + if let _ = connectedPorts.first(where: { x in x.path.elementsEqual(self.port.path) }){ + self.isConnect.send(true) + } + } + } + .store(in: &self.subSet) + + NotificationCenter.default + .publisher(for: NSNotification.Name.ORSSerialPortsWereDisconnected) + .sink() { notification in + if let userInfo = notification.userInfo { + let disconnectedPorts: [ORSSerialPort] = userInfo[ORSDisconnectedSerialPortsKey] as! [ORSSerialPort] + if let _ = disconnectedPorts.first(where: { x in x.path.elementsEqual(self.port.path) }){ + self.isConnect.send(false) + self.isOpen.send(false) + } + } + } + .store(in: &self.subSet) + } + + func initKVOSub(){ + + port.publisher(for: \.cts) + .sink{ _ in self.portSettings.send(PortSettings(self.port,isConnect: self.isConnect.value))} + .store(in: &subSet) + port.publisher(for: \.dsr) + .sink{ _ in self.portSettings.send(PortSettings(self.port,isConnect: self.isConnect.value))} + .store(in: &subSet) + port.publisher(for: \.dcd) + .sink{ value in self.portSettings.send(PortSettings(self.port,isConnect: self.isConnect.value))} + .store(in: &subSet) + port.publisher(for: \.rts) + .sink{value in + if (self.rts != value){ + self.rts = value + self.portSettings.send(PortSettings(self.port,isConnect: self.isConnect.value)) + }} + .store(in: &subSet) + port.publisher(for: \.dtr) + .sink{ value in + if(self.dtr != value){ + self.portSettings.send(PortSettings(self.port,isConnect: self.isConnect.value)) + self.dtr = value } + } + .store(in: &subSet) + +// port.publisher(for: \.pendingRequest) +// .sink{ value in self.pendingRequest = value } +// .store(in: &subSet) +// port.publisher(for: \.queuedRequests) +// .sink{ value in self.queuedRequests = value } +// .store(in: &subSet) + } + +} + +extension ORSSerialPortCombine: ORSSerialPortDelegate{ + + func serialPortWasRemovedFromSystem(_ serialPort: ORSSerialPort){ + isConnect.send(false) + isOpen.send(false) + } + + func serialPort(_ serialPort: ORSSerialPort, didReceive data: Data){ + receiveData.send(data) + } + + func serialPort(_ serialPort: ORSSerialPort, didReceivePacket packetData: Data, matching descriptor: ORSSerialPacketDescriptor){ + receivePacket.send((packetData,descriptor)) + } + + func serialPort(_ serialPort: ORSSerialPort, didReceiveResponse responseData: Data, to request: ORSSerialRequest){ + self.responseData.send((responseData, request)) + } + + func serialPort(_ serialPort: ORSSerialPort, requestDidTimeout request: ORSSerialRequest){ + requestTimeout.send(request) + } + + func serialPort(_ serialPort: ORSSerialPort, didEncounterError error: Error){ + self.error.send(error) + } + + func serialPortWasOpened(_ serialPort: ORSSerialPort){ + isOpen.send(true) + } + + func serialPortWasClosed(_ serialPort: ORSSerialPort){ + isOpen.send(false) + } + +} + + + + + +extension ORSSerialPortParity { + static func allCases() -> [ORSSerialPortParity] { [.none,.odd,.even] } + func description() -> String { + switch self { + case .none: return "None" + case .odd: return "Odd" + case .even: return "Even" + @unknown default: return "@unknown" + } + } +} + diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/ViewModel.swift b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/ViewModel.swift new file mode 100644 index 00000000..f2ed224c --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Demo/ViewModel.swift @@ -0,0 +1,116 @@ +// +// ViewModel.swift +// SerialPort +// +// Created by Jan Anstipp on 30.09.20. +// + +import Foundation +import ORSSerial +import SwiftUI +import Combine + +class ViewModel: ObservableObject{ + + @Published var settings = PortSettings() + @Published var settingsDebug = PortSettings() + @Published var serialPort: ORSSerialPortCombine? + @Published var availablePorts: [String] = [] + @Published var path: String = "" + @Published var recieve: String = "" + + + private var subSet = Set() + private var manager = ORSSerialPortManager.shared() + + init(){ + $path.sink{self.newPort($0)}.store(in: &subSet) + manager.publisher(for: \.availablePorts).map{ $0.map{$0.path} }.assign(to: \.availablePorts, on: self).store(in: &subSet) + } + + private func newPort(_ path: String){ + serialPort = ORSSerialPortCombine(path) + serialPort?.portSettingsSub + .assign(to: \.settings, on: self) + .store(in: &subSet) + + serialPort?.receiveDataSub + .sink{data in + self.recieve += String(decoding: data, as: UTF8.self) + }.store(in: &subSet) + } + +} + +struct PortSettings{ + var path: String = "" + var name: String = "" + var isOpen: Bool = false + var isConnect: Bool = false + var cts: Bool = false + var dsr: Bool = false + var usesDCDOutputFlowControl: Bool = false + var baudRate: Int = 9600 + var numberOfStopBits: Int = 1 + var usesRTSCTSFlowControl: Bool = false + var usesDTRDSRFlowControl: Bool = false + var rts: Bool = false + var dtr: Bool = false + var dcdIn: Bool = false + var echo: Bool = false + var parity: ORSSerialPortParity = .none + var numberOfDataBits: Int = 0 + var allowsNonStandardBaudRates: Bool = false + init(){} +} + +extension PortSettings{ + + init(_ port: ORSSerialPort,isConnect: Bool){ + baudRate = Int(truncating: port.baudRate) + numberOfStopBits = Int(port.numberOfStopBits) + parity = port.parity + usesRTSCTSFlowControl = port.usesRTSCTSFlowControl + usesDTRDSRFlowControl = port.usesDTRDSRFlowControl + usesDCDOutputFlowControl = port.usesDCDOutputFlowControl + echo = port.shouldEchoReceivedData + rts = port.rts + dtr = port.dtr + numberOfDataBits = Int(port.numberOfDataBits) + self.isConnect = isConnect + isOpen = port.isOpen + name = port.name + path = port.path + cts = port.cts + dsr = port.dsr + dcdIn = port.dcd + allowsNonStandardBaudRates = port.allowsNonStandardBaudRates + } +} + +// For debugging + +extension ViewModel { + func updatePortTestSetting(){ + guard let port = serialPort?.port else { return } + settingsDebug.path = port.path + settingsDebug.name = port.name + settingsDebug.cts = port.cts + settingsDebug.dsr = port.dsr + settingsDebug.usesDCDOutputFlowControl = port.usesDCDOutputFlowControl + settingsDebug.baudRate = Int(truncating: port.baudRate) + settingsDebug.numberOfStopBits = Int(port.numberOfStopBits) + settingsDebug.usesRTSCTSFlowControl = port.usesRTSCTSFlowControl + settingsDebug.usesDTRDSRFlowControl = port.usesDTRDSRFlowControl + settingsDebug.rts = port.rts + settingsDebug.dtr = port.dtr + settingsDebug.dcdIn = port.dcd + settingsDebug.echo = port.shouldEchoReceivedData + settingsDebug.parity = port.parity + settingsDebug.numberOfDataBits = Int(port.numberOfDataBits) + settingsDebug.allowsNonStandardBaudRates = port.allowsNonStandardBaudRates + settingsDebug.isOpen = port.isOpen + + } + +} diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Info.plist b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Info.plist new file mode 100644 index 00000000..cfbbdb70 --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSMainStoryboardFile + Main + NSPrincipalClass + NSApplication + + diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/SwiftUIDemo.entitlements b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/SwiftUIDemo.entitlements new file mode 100644 index 00000000..97a8d921 --- /dev/null +++ b/Examples/ORSSerialSwiftUIDemo/Swift/SwiftUIDemo/SwiftUIDemo/SwiftUIDemo.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.device.usb + + com.apple.security.files.user-selected.read-only + + com.apple.security.device.serial + + +