diff --git a/Documentation/GettingStarted.md b/Documentation/GettingStarted.md
index 8ea04fd4..c9052153 100644
--- a/Documentation/GettingStarted.md
+++ b/Documentation/GettingStarted.md
@@ -20,7 +20,11 @@ During the alpha phase, the app is not in available in the App Store. [Click her
## Installation
-### Swift Package Manager
+### Package
+
+You can add the library to your XCode project via Swift Package Manager. See "[Adding package dependencies to your app](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app)".
+
+If you want to add it to your own libraries `Package.swift`, use this code instead:
```swift
dependencies: [
@@ -28,24 +32,12 @@ dependencies: [
]
```
-### CocoaPods
-
-Example Podfile
+### Entitlements
-```Ruby
-platform :ios, '16.0'
-
-target 'YourAppTarget' do
- use_frameworks!
- pod 'StreamDeckKit'
- pod 'StreamDeckSimulator', :configurations => ['Debug']
-end
-```
+In order to connect to the Stream Deck driver, you need to add the "[Communicates with Drivers](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_driverkit_communicates-with-drivers)" (`com.apple.developer.driverkit.communicates-with-drivers`) capability to your app target. Refer to "[Adding capabilities to your app](https://developer.apple.com/documentation/xcode/adding-capabilities-to-your-app/)" for guidance.
## First steps
-First, add the [DriverKit Communicates with Drivers](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_driverkit_communicates-with-drivers) capability to your app target. Refer to [Adding capabilities to your app](https://developer.apple.com/documentation/xcode/adding-capabilities-to-your-app/) for guidance.
-
Rendering content on a Stream Deck is very simple with SwiftUI, much like designing a typical app UI.
```swift
@@ -74,15 +66,15 @@ struct MyFirstStreamDeckLayout {
StreamDeckLayout {
// Define key area
// Use StreamDeckKeyAreaLayout for rendering separate keys
- StreamDeckKeyAreaLayout { context in
+ StreamDeckKeyAreaLayout { keyIndex in
// Define content for each key.
- // StreamDeckKeyAreaLayout provides a context for each available key,
+ // StreamDeckKeyAreaLayout provides an index for each available key,
// and StreamDeckKeyView provides a callback for the key action
// Example:
StreamDeckKeyView { pressed in
print("pressed \(pressed)")
} content: {
- Text("\(context.index)")
+ Text("\(keyIndex)")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.teal)
}
diff --git a/Documentation/Layout/README.md b/Documentation/Layout/README.md
index 0a63cce3..f213773d 100644
--- a/Documentation/Layout/README.md
+++ b/Documentation/Layout/README.md
@@ -44,15 +44,15 @@ struct StatelessStreamDeckLayout {
StreamDeckLayout {
// Define key area
// Use StreamDeckKeyAreaLayout for rendering separate keys
- StreamDeckKeyAreaLayout { context in
+ StreamDeckKeyAreaLayout { keyIndex in
// Define content for each key.
- // StreamDeckKeyAreaLayout provides a context for each available key,
+ // StreamDeckKeyAreaLayout provides an index for each available key,
// and StreamDeckKeyView provides a callback for the key action
// Example:
StreamDeckKeyView { pressed in
print("pressed \(pressed)")
} content: {
- Text("\(context.index)")
+ Text("\(keyIndex)")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.teal)
}
@@ -60,9 +60,9 @@ struct StatelessStreamDeckLayout {
} windowArea: {
// Define window area
// Use StreamDeckDialAreaLayout for rendering separate parts of the display
- StreamDeckDialAreaLayout { context in
+ StreamDeckDialAreaLayout { dialIndex in
// Define content for each dial
- // StreamDeckDialAreaLayout provides a context for each available dial,
+ // StreamDeckDialAreaLayout provides an index for each available dial,
// and StreamDeckDialView provides callbacks for the dial actions
// Example:
StreamDeckDialView { rotations in
@@ -72,9 +72,9 @@ struct StatelessStreamDeckLayout {
} touch: { location in
print("touched at \(location)")
} content: {
- Text("\(context.index)")
+ Text("\(dialIndex)")
.frame(maxWidth: .infinity, maxHeight: .infinity)
- .background(Color(white: Double(context.index) / 5 + 0.5))
+ .background(Color(white: Double(dialIndex) / 5 + 0.5))
}
}
}.background(.indigo)
diff --git a/Example/Example App/Examples/1_StatelessStreamDeckLayout.swift b/Example/Example App/Examples/1_StatelessStreamDeckLayout.swift
index 2dfc6d15..d5b332bb 100644
--- a/Example/Example App/Examples/1_StatelessStreamDeckLayout.swift
+++ b/Example/Example App/Examples/1_StatelessStreamDeckLayout.swift
@@ -15,15 +15,15 @@ struct StatelessStreamDeckLayout {
StreamDeckLayout {
// Define key area
// Use StreamDeckKeyAreaLayout for rendering separate keys
- StreamDeckKeyAreaLayout { context in
+ StreamDeckKeyAreaLayout { keyIndex in
// Define content for each key.
- // StreamDeckKeyAreaLayout provides a context for each available key,
+ // StreamDeckKeyAreaLayout provides an index for each available key,
// and StreamDeckKeyView provides a callback for the key action
// Example:
StreamDeckKeyView { pressed in
print("pressed \(pressed)")
} content: {
- Text("\(context.index)")
+ Text("\(keyIndex)")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.teal)
}
@@ -31,9 +31,9 @@ struct StatelessStreamDeckLayout {
} windowArea: {
// Define window area
// Use StreamDeckDialAreaLayout for rendering separate parts of the display
- StreamDeckDialAreaLayout { context in
+ StreamDeckDialAreaLayout { dialIndex in
// Define content for each dial
- // StreamDeckDialAreaLayout provides a context for each available dial,
+ // StreamDeckDialAreaLayout provides an index for each available dial,
// and StreamDeckDialView provides callbacks for the dial actions
// Example:
StreamDeckDialView { rotations in
@@ -43,9 +43,9 @@ struct StatelessStreamDeckLayout {
} touch: { location in
print("touched at \(location)")
} content: {
- Text("\(context.index)")
+ Text("\(dialIndex)")
.frame(maxWidth: .infinity, maxHeight: .infinity)
- .background(Color(white: Double(context.index) / 5 + 0.5))
+ .background(Color(white: Double(dialIndex) / 5 + 0.5))
}
}
}.background(.indigo)
diff --git a/Example/Example App/StreamDeckKitExampleApp.swift b/Example/Example App/StreamDeckKitExampleApp.swift
index 0a3e0317..dc8f52e0 100644
--- a/Example/Example App/StreamDeckKitExampleApp.swift
+++ b/Example/Example App/StreamDeckKitExampleApp.swift
@@ -16,9 +16,10 @@ struct StreamDeckKitExampleApp: App {
// Uncomment the next line to enable StreamDeckKit internal logging.
// streamDeckLoggingHandler = { os_log($0, "\($1)") }
- StreamDeckSession.setUp(newDeviceHandler: {
- $0.render(BaseStreamDeckView())
- })
+ StreamDeckSession.setUp(
+ stateHandler: { os_log("Stream Deck session state: %s", String(describing: $0)) },
+ newDeviceHandler: { $0.render(BaseStreamDeckView()) }
+ )
}
var body: some Scene {
diff --git a/Gemfile b/Gemfile
deleted file mode 100644
index fb666243..00000000
--- a/Gemfile
+++ /dev/null
@@ -1,3 +0,0 @@
-source "https://rubygems.org"
-
-gem "cocoapods", '~>1.14'
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
deleted file mode 100644
index c6fe1b3c..00000000
--- a/Gemfile.lock
+++ /dev/null
@@ -1,107 +0,0 @@
-GEM
- remote: https://rubygems.org/
- specs:
- CFPropertyList (3.0.6)
- rexml
- activesupport (7.1.2)
- base64
- bigdecimal
- concurrent-ruby (~> 1.0, >= 1.0.2)
- connection_pool (>= 2.2.5)
- drb
- i18n (>= 1.6, < 2)
- minitest (>= 5.1)
- mutex_m
- tzinfo (~> 2.0)
- addressable (2.8.6)
- public_suffix (>= 2.0.2, < 6.0)
- algoliasearch (1.27.5)
- httpclient (~> 2.8, >= 2.8.3)
- json (>= 1.5.1)
- atomos (0.1.3)
- base64 (0.2.0)
- bigdecimal (3.1.5)
- claide (1.1.0)
- cocoapods (1.14.3)
- addressable (~> 2.8)
- claide (>= 1.0.2, < 2.0)
- cocoapods-core (= 1.14.3)
- cocoapods-deintegrate (>= 1.0.3, < 2.0)
- cocoapods-downloader (>= 2.1, < 3.0)
- cocoapods-plugins (>= 1.0.0, < 2.0)
- cocoapods-search (>= 1.0.0, < 2.0)
- cocoapods-trunk (>= 1.6.0, < 2.0)
- cocoapods-try (>= 1.1.0, < 2.0)
- colored2 (~> 3.1)
- escape (~> 0.0.4)
- fourflusher (>= 2.3.0, < 3.0)
- gh_inspector (~> 1.0)
- molinillo (~> 0.8.0)
- nap (~> 1.0)
- ruby-macho (>= 2.3.0, < 3.0)
- xcodeproj (>= 1.23.0, < 2.0)
- cocoapods-core (1.14.3)
- activesupport (>= 5.0, < 8)
- addressable (~> 2.8)
- algoliasearch (~> 1.0)
- concurrent-ruby (~> 1.1)
- fuzzy_match (~> 2.0.4)
- nap (~> 1.0)
- netrc (~> 0.11)
- public_suffix (~> 4.0)
- typhoeus (~> 1.0)
- cocoapods-deintegrate (1.0.5)
- cocoapods-downloader (2.1)
- cocoapods-plugins (1.0.0)
- nap
- cocoapods-search (1.0.1)
- cocoapods-trunk (1.6.0)
- nap (>= 0.8, < 2.0)
- netrc (~> 0.11)
- cocoapods-try (1.2.0)
- colored2 (3.1.2)
- concurrent-ruby (1.2.2)
- connection_pool (2.4.1)
- drb (2.2.0)
- ruby2_keywords
- escape (0.0.4)
- ethon (0.16.0)
- ffi (>= 1.15.0)
- ffi (1.16.3)
- fourflusher (2.3.1)
- fuzzy_match (2.0.4)
- gh_inspector (1.1.3)
- httpclient (2.8.3)
- i18n (1.14.1)
- concurrent-ruby (~> 1.0)
- json (2.7.1)
- minitest (5.20.0)
- molinillo (0.8.0)
- mutex_m (0.2.0)
- nanaimo (0.3.0)
- nap (1.1.0)
- netrc (0.11.0)
- public_suffix (4.0.7)
- rexml (3.2.6)
- ruby-macho (2.5.1)
- ruby2_keywords (0.0.5)
- typhoeus (1.4.1)
- ethon (>= 0.9.0)
- tzinfo (2.0.6)
- concurrent-ruby (~> 1.0)
- xcodeproj (1.23.0)
- CFPropertyList (>= 2.3.3, < 4.0)
- atomos (~> 0.1.3)
- claide (>= 1.0.2, < 2.0)
- colored2 (~> 3.1)
- nanaimo (~> 0.3.0)
- rexml (~> 3.2.4)
-
-PLATFORMS
- arm64-darwin-23
-
-DEPENDENCIES
- cocoapods (~> 1.14)
-
-BUNDLED WITH
- 2.4.22
diff --git a/README.md b/README.md
index ec8b015d..71d49763 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,9 @@
Stream Deck Kit is a Swift Library for controlling physical [Elgato Stream Deck](https://www.elgato.com/stream-deck) devices with an iPadOS app.
-
-
-
+
+
+
## Features
@@ -46,7 +46,11 @@ However, if you want to verify your implementation using the [Stream Deck Simula
## Installation
-### Swift Package Manager
+### Package
+
+You can add the library to your XCode project via Swift Package Manager. See "[Adding package dependencies to your app](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app)".
+
+If you want to add it to your own libraries `Package.swift`, use this code instead:
```swift
dependencies: [
@@ -54,24 +58,12 @@ dependencies: [
]
```
-### CocoaPods
-
-Example Podfile
+### Entitlements
-```Ruby
-platform :ios, '16.0'
-
-target 'YourAppTarget' do
- use_frameworks!
- pod 'StreamDeckKit'
- pod 'StreamDeckSimulator', :configurations => ['Debug']
-end
-```
+In order to connect to the Stream Deck driver, you need to add the "[Communicates with Drivers](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_driverkit_communicates-with-drivers)" (`com.apple.developer.driverkit.communicates-with-drivers`) capability to your app target. Refer to "[Adding capabilities to your app](https://developer.apple.com/documentation/xcode/adding-capabilities-to-your-app/)" for guidance.
## Getting started
-First, add the [DriverKit Communicates with Drivers](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_driverkit_communicates-with-drivers) capability to your app target. Refer to [Adding capabilities to your app](https://developer.apple.com/documentation/xcode/adding-capabilities-to-your-app/) for guidance.
-
Rendering content on a Stream Deck is very simple with SwiftUI, much like designing a typical app UI.
```swift
diff --git a/Sources/StreamDeckCApi/StreamDeckCApi.c b/Sources/StreamDeckCApi/StreamDeckCApi.c
index 9ea2c35d..494438f3 100644
--- a/Sources/StreamDeckCApi/StreamDeckCApi.c
+++ b/Sources/StreamDeckCApi/StreamDeckCApi.c
@@ -27,3 +27,5 @@
#include
#import "include/StreamDeckCApi.h"
+
+const IOReturn sdkIOReturnNotPermitted = kIOReturnNotPermitted;
diff --git a/Sources/StreamDeckCApi/include/StreamDeckCApi.h b/Sources/StreamDeckCApi/include/StreamDeckCApi.h
index 6d455718..0c22c577 100644
--- a/Sources/StreamDeckCApi/include/StreamDeckCApi.h
+++ b/Sources/StreamDeckCApi/include/StreamDeckCApi.h
@@ -31,4 +31,7 @@
#include
#include "StreamDeckDriverShared.h"
+/// Exported error constant to handle problems with "Communicates with Driver" capability in Swift.
+extern const IOReturn sdkIOReturnNotPermitted;
+
#endif /* StreamDeckCApi_h */
diff --git a/Sources/StreamDeckKit/Layout/StreamDeckDialAreaLayout.swift b/Sources/StreamDeckKit/Layout/StreamDeckDialAreaLayout.swift
index 9f9a1f69..81ad5e23 100644
--- a/Sources/StreamDeckKit/Layout/StreamDeckDialAreaLayout.swift
+++ b/Sources/StreamDeckKit/Layout/StreamDeckDialAreaLayout.swift
@@ -41,9 +41,10 @@ public struct StreamDeckDialAreaLayout: View {
/// A handler for press events on a rotary encoder(dial).
///
/// The first parameter is the index of the dial. The second one indicates if the dial is down or not.
- public typealias DialPressHandler = @MainActor (Int, Bool) -> Void
+ public typealias DialPressHandler = @MainActor (_ index: Int, _ isPressed: Bool) -> Void
public typealias TouchHandler = @MainActor (CGPoint) -> Void
- public typealias FlingHandler = @MainActor (CGPoint, CGPoint, InputEvent.Direction) -> Void
+ public typealias FlingHandler = @MainActor (_ start: CGPoint, _ end: CGPoint, _ direction: InputEvent.Direction) -> Void
+ public typealias DialProvider = @MainActor (_ keyIndex: Int) -> Dial
@Environment(\.streamDeckViewContext) private var context
@@ -51,14 +52,14 @@ public struct StreamDeckDialAreaLayout: View {
private let press: DialPressHandler?
private let touch: TouchHandler?
private let fling: FlingHandler?
- @ViewBuilder private let dial: @MainActor (StreamDeckViewContext) -> Dial
+ @ViewBuilder private let dial: DialProvider
public init(
rotate: DialRotationHandler? = nil,
press: DialPressHandler? = nil,
touch: TouchHandler? = nil,
fling: FlingHandler? = nil,
- @ViewBuilder dial: @escaping @MainActor (StreamDeckViewContext) -> Dial
+ @ViewBuilder dial: @escaping DialProvider
) {
self.rotate = rotate
self.press = press
@@ -72,7 +73,7 @@ public struct StreamDeckDialAreaLayout: View {
press: @escaping @MainActor (Int) -> Void,
touch: TouchHandler? = nil,
fling: FlingHandler? = nil,
- @ViewBuilder dial: @escaping @MainActor (StreamDeckViewContext) -> Dial
+ @ViewBuilder dial: @escaping DialProvider
) {
self.init(
rotate: rotate,
@@ -96,7 +97,7 @@ public struct StreamDeckDialAreaLayout: View {
index: section
)
- dial(dialContext)
+ dial(dialContext.index)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.environment(\.streamDeckViewContext, dialContext)
}
diff --git a/Sources/StreamDeckKit/Layout/StreamDeckKeypadLayout.swift b/Sources/StreamDeckKit/Layout/StreamDeckKeypadLayout.swift
index f85cf6c5..399fb60c 100644
--- a/Sources/StreamDeckKit/Layout/StreamDeckKeypadLayout.swift
+++ b/Sources/StreamDeckKit/Layout/StreamDeckKeypadLayout.swift
@@ -35,7 +35,7 @@ public struct StreamDeckKeyAreaLayout: View {
/// A factory function that provides a view for a key.
///
/// Use the ``StreamDeckViewContext/index`` property of the context parameter to distinguish keys.
- public typealias KeyViewProvider = @MainActor (StreamDeckViewContext) -> Key
+ public typealias KeyViewProvider = @MainActor (_ keyIndex: Int) -> Key
@Environment(\.streamDeckViewContext) private var context
@@ -67,7 +67,7 @@ public struct StreamDeckKeyAreaLayout: View {
index: position
)
- keyView(keyContext)
+ keyView(keyContext.index)
.frame(width: keySize.width, height: keySize.height)
.environment(\.streamDeckViewContext, keyContext)
}
diff --git a/Sources/StreamDeckKit/Session/InternalStreamDeckSession.swift b/Sources/StreamDeckKit/Session/InternalStreamDeckSession.swift
index 47aaf016..7ca38229 100644
--- a/Sources/StreamDeckKit/Session/InternalStreamDeckSession.swift
+++ b/Sources/StreamDeckKit/Session/InternalStreamDeckSession.swift
@@ -99,6 +99,9 @@ final actor InternalStreamDeckSession {
guard ret == kIOReturnSuccess else {
os_log(.error, "Failed opening service with error: \(String(ioReturn: ret)).")
+ if ret == sdkIOReturnNotPermitted {
+ state.value = .failed(.missingEntitlement)
+ }
continue
}
diff --git a/Sources/StreamDeckKit/Session/StreamDeckSession.State+CustomDebugStringConvertible.swift b/Sources/StreamDeckKit/Session/StreamDeckSession.State+CustomDebugStringConvertible.swift
index 1fd103b4..d20aa2fb 100644
--- a/Sources/StreamDeckKit/Session/StreamDeckSession.State+CustomDebugStringConvertible.swift
+++ b/Sources/StreamDeckKit/Session/StreamDeckSession.State+CustomDebugStringConvertible.swift
@@ -36,6 +36,7 @@ extension StreamDeckSession.State: CustomDebugStringConvertible {
switch sessionError {
case .unexpectedDriverError: return ".failed(.unexpectedDriverError)"
case .driverVersionMismatch: return ".failed(.driverVersionMismatch)"
+ case .missingEntitlement: return ".failed(.missingEntitlement)"
}
}
}
diff --git a/Sources/StreamDeckKit/Session/StreamDeckSession.swift b/Sources/StreamDeckKit/Session/StreamDeckSession.swift
index dd547647..df7df6a4 100644
--- a/Sources/StreamDeckKit/Session/StreamDeckSession.swift
+++ b/Sources/StreamDeckKit/Session/StreamDeckSession.swift
@@ -72,6 +72,9 @@ public final class StreamDeckSession {
case unexpectedDriverError
/// The driver has a different major version. Either the SDK or the driver app needs an update.
case driverVersionMismatch
+ /// The app needs to have the "Communicates with Drivers"
+ /// (com.apple.developer.driverkit.communicates-with-drivers) capability set in its entitlements.
+ case missingEntitlement
}
/// Reflects the current state of a StreamDeck session.
diff --git a/Sources/StreamDeckSimulator/StreamDeckSimulatorClient.swift b/Sources/StreamDeckSimulator/StreamDeckSimulatorClient.swift
index ea078bbb..e02aecb4 100644
--- a/Sources/StreamDeckSimulator/StreamDeckSimulatorClient.swift
+++ b/Sources/StreamDeckSimulator/StreamDeckSimulatorClient.swift
@@ -31,7 +31,7 @@ import StreamDeckCApi
import StreamDeckKit
import UIKit
-public final class StreamDeckSimulatorClient {
+final class StreamDeckSimulatorClient {
private let capabilities: DeviceCapabilities
private let brightnessSubject = CurrentValueSubject(0)
diff --git a/Sources/StreamDeckSimulator/Views/SimulatorTouchView.swift b/Sources/StreamDeckSimulator/Views/SimulatorTouchView.swift
index a4bb731e..8860e606 100644
--- a/Sources/StreamDeckSimulator/Views/SimulatorTouchView.swift
+++ b/Sources/StreamDeckSimulator/Views/SimulatorTouchView.swift
@@ -28,24 +28,34 @@
import SwiftUI
import StreamDeckKit
-struct SimulatorTouchView: View {
+@StreamDeckView
+struct SimulatorTouchView {
- let onTouch: (CGPoint) -> Void
- let onFling: (CGPoint, CGPoint) -> Void
+ let client: StreamDeckSimulatorClient?
- var body: some View {
+ var streamDeckBody: some View {
StreamDeckDialView {
Color.clear
}
.contentShape(Rectangle())
.frame(maxWidth: .infinity, maxHeight: .infinity)
- .onTapGesture(coordinateSpace: .local) { location in
- onTouch(location)
+ .onTapGesture(coordinateSpace: .local) { localLocation in
+ guard let client = client else { return }
+ let x = CGFloat(viewIndex) * viewSize.width + localLocation.x
+ Task { await client.emit(.touch(.init(x: x, y: localLocation.y))) }
}
.gesture(
DragGesture(minimumDistance: 10, coordinateSpace: .local)
.onEnded { value in
- onFling(value.startLocation, value.location)
+ guard let client = client else { return }
+ let startX = CGFloat(viewIndex) * viewSize.width + value.startLocation.x
+ let endX = CGFloat(viewIndex) * viewSize.width + value.location.x
+ Task {
+ await client.emit(.fling(
+ start: .init(x: startX, y: value.startLocation.y),
+ end: .init(x: endX, y: value.location.y)
+ ))
+ }
}
)
}
diff --git a/Sources/StreamDeckSimulator/Views/StreamDeckSimulatorView.swift b/Sources/StreamDeckSimulator/Views/StreamDeckSimulatorView.swift
index b8afeff6..4a6e1335 100644
--- a/Sources/StreamDeckSimulator/Views/StreamDeckSimulatorView.swift
+++ b/Sources/StreamDeckSimulator/Views/StreamDeckSimulatorView.swift
@@ -169,22 +169,12 @@ private extension StreamDeckSimulatorView {
@ViewBuilder
var touchPad: some View {
StreamDeckLayout {
- StreamDeckKeyAreaLayout { context in
- SimulatorKeyView(client: client, index: context.index)
+ StreamDeckKeyAreaLayout { keyIndex in
+ SimulatorKeyView(client: client, index: keyIndex)
}
} windowArea: {
- StreamDeckDialAreaLayout { context in
- SimulatorTouchView { localLocation in
- let x = CGFloat(context.index) * context.size.width + localLocation.x
- client.emit(.touch(.init(x: x, y: localLocation.y)))
- } onFling: { startLocation, endLocation in
- let startX = CGFloat(context.index) * context.size.width + startLocation.x
- let endX = CGFloat(context.index) * context.size.width + endLocation.x
- client.emit(.fling(
- start: .init(x: startX, y: startLocation.y),
- end: .init(x: endX, y: endLocation.y)
- ))
- }
+ StreamDeckDialAreaLayout { _ in
+ SimulatorTouchView(client: client)
}
}
.background {
@@ -216,7 +206,7 @@ private extension StreamDeckSimulatorView {
}
} windowArea: {
StreamDeckDialAreaLayout { _ in
- SimulatorTouchView { _ in } onFling: { _, _ in }
+ SimulatorTouchView(client: nil)
.background {
Color.clear.border(.red)
}
diff --git a/StreamDeckCApi.podspec b/StreamDeckCApi.podspec
deleted file mode 100644
index 0325afe7..00000000
--- a/StreamDeckCApi.podspec
+++ /dev/null
@@ -1,22 +0,0 @@
-Pod::Spec.new do |s|
- s.name = 'StreamDeckCApi'
- s.version = '0.0.1'
- s.swift_version = '5.9'
-
- s.summary = 'C header for StreamDeckKit. Not for standalone use.'
- s.author = { 'Elgato' => 'info@elgato.com' }
- s.homepage = 'https://docs.elgato.com/ipad'
- s.license = { :type => 'MIT', :file => 'LICENSE' }
- s.source = { :git => 'https://github.com/elgatosf/streamdeck-kit-ipad.git', :tag => "#{s.version}" }
-
- s.requires_arc = true
- s.frameworks = 'IOKit'
- s.source_files = "Sources/#{s.name}/**/*.{c,h}"
- s.public_header_files = "Sources/#{s.name}/**/*.h"
-
- # See: https://github.com/CocoaPods/CocoaPods/issues/12073#issuecomment-1737821281
- s.xcconfig = { 'ENABLE_USER_SCRIPT_SANDBOXING' => false }
-
- s.platform = :ios, '16.0'
- s.ios.deployment_target = '16'
-end
diff --git a/StreamDeckKit.podspec b/StreamDeckKit.podspec
deleted file mode 100644
index 8482f940..00000000
--- a/StreamDeckKit.podspec
+++ /dev/null
@@ -1,19 +0,0 @@
-Pod::Spec.new do |s|
- s.name = 'StreamDeckKit'
- s.version = '0.0.1'
- s.swift_version = '5.9'
-
- s.summary = 'Integrate StreamDeck hardware into your App'
- s.author = { 'Elgato' => 'info@elgato.com' }
- s.homepage = 'https://docs.elgato.com/ipad'
- s.license = { :type => 'MIT', :file => 'LICENSE' }
- s.source = { :git => 'https://github.com/elgatosf/streamdeck-kit-ipad.git', :tag => "#{s.version}" }
-
- s.requires_arc = true
- s.frameworks = 'UIKit', 'SwiftUI'
- s.source_files = "Sources/#{s.name}/**/*.swift"
- s.dependency 'StreamDeckCApi', "#{s.version.to_s}"
-
- s.platform = :ios, '16.0'
- s.ios.deployment_target = '16'
-end
diff --git a/StreamDeckSimulator.podspec b/StreamDeckSimulator.podspec
deleted file mode 100644
index 0b577282..00000000
--- a/StreamDeckSimulator.podspec
+++ /dev/null
@@ -1,22 +0,0 @@
-Pod::Spec.new do |s|
- s.name = 'StreamDeckSimulator'
- s.version = '0.0.1'
- s.swift_version = '5.9'
-
- s.summary = 'Simulate different StreamDeck devices to test your StreamDeckKit integration.'
- s.author = { 'Elgato' => 'info@elgato.com' }
- s.homepage = 'https://docs.elgato.com/ipad'
- s.license = { :type => 'MIT', :file => 'LICENSE' }
- s.source = { :git => 'https://github.com/elgatosf/streamdeck-kit-ipad.git', :tag => "#{s.version}" }
-
- s.requires_arc = true
- s.source_files = "Sources/#{s.name}/**/*.swift"
- s.dependency 'StreamDeckKit', "#{s.version.to_s}"
-
- # To be compatible with SPM integration, we give the resource bundle the same name as SPM would do.
- # See: https://medium.com/clutter-engineering/supporting-both-swift-package-manager-and-cocoapods-in-your-library-861f00b6b0f9#8694
- s.resource_bundles = { "StreamDeckKit_#{s.name}" => ["Sources/#{s.name}/Resources/**/*"] }
-
- s.platform = :ios, '16.0'
- s.ios.deployment_target = '16'
-end
diff --git a/Tests/StreamDeckSDKTests/StreamDeckLayoutTests.swift b/Tests/StreamDeckSDKTests/StreamDeckLayoutTests.swift
index 48c116f5..35926221 100644
--- a/Tests/StreamDeckSDKTests/StreamDeckLayoutTests.swift
+++ b/Tests/StreamDeckSDKTests/StreamDeckLayoutTests.swift
@@ -141,9 +141,9 @@ final class StreamDeckLayoutTests: XCTestCase {
var events = [(index: Int, pressed: Bool)]()
try await robot.use(.pedal, rendering: StreamDeckLayout(keyArea: {
- StreamDeckKeyAreaLayout { context in
+ StreamDeckKeyAreaLayout { keyIndex in
StreamDeckKeyView { pressed in
- events.append((index: context.index, pressed: pressed))
+ events.append((index: keyIndex, pressed: pressed))
} content: { EmptyView() }
}
}), waitForLayout: false)