Skip to content

Commit b63c2d4

Browse files
committed
Merge branch 'main' of github.com:square/workflow-swift into tomb/swiftui-testbed
* 'main' of github.com:square/workflow-swift: Add WorkflowSwiftUIExperimental (#252) Add convenience method for library definitions to reduce boilerplate (#251) [release]: bump to version 3.4.0 (#250) RxSwift 6.6 (#212) Expose 'screen' on WorkflowHostingController (#246) [fix]: address some RenderTester limitations with optionals (#245) Resolved Swift 5.9 compilation warning related to UnsafeRawPointer object conversion (#243) Bump activesupport from 6.1.7.3 to 6.1.7.6 (#242)
2 parents 61e8bb7 + ada3b7e commit b63c2d4

20 files changed

+452
-95
lines changed

Diff for: Development.podspec

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Pod::Spec.new do |s|
1717
s.dependency 'WorkflowRxSwift'
1818
s.dependency 'WorkflowCombine'
1919
s.dependency 'WorkflowConcurrency'
20+
s.dependency 'WorkflowSwiftUIExperimental'
2021
s.dependency 'ViewEnvironment'
2122
s.dependency 'ViewEnvironmentUI'
2223

Diff for: Gemfile.lock

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ GEM
33
specs:
44
CFPropertyList (3.0.5)
55
rexml
6-
activesupport (6.1.7.3)
6+
activesupport (6.1.7.6)
77
concurrent-ruby (~> 1.0, >= 1.0.2)
88
i18n (>= 1.6, < 2)
99
minitest (>= 5.1)
@@ -66,10 +66,10 @@ GEM
6666
fuzzy_match (2.0.4)
6767
gh_inspector (1.1.3)
6868
httpclient (2.8.3)
69-
i18n (1.12.0)
69+
i18n (1.14.1)
7070
concurrent-ruby (~> 1.0)
7171
json (2.6.1)
72-
minitest (5.18.0)
72+
minitest (5.19.0)
7373
molinillo (0.8.0)
7474
nanaimo (0.3.0)
7575
nap (1.1.0)
@@ -88,7 +88,7 @@ GEM
8888
colored2 (~> 3.1)
8989
nanaimo (~> 0.3.0)
9090
rexml (~> 3.2.4)
91-
zeitwerk (2.6.7)
91+
zeitwerk (2.6.11)
9292

9393
PLATFORMS
9494
ruby

Diff for: Package.swift

+25-57
Original file line numberDiff line numberDiff line change
@@ -12,87 +12,45 @@ let package = Package(
1212
products: [
1313
// MARK: Workflow
1414

15-
.library(
16-
name: "Workflow",
17-
targets: ["Workflow"]
18-
),
19-
.library(
20-
name: "WorkflowTesting",
21-
targets: ["WorkflowTesting"]
22-
),
15+
.singleTargetLibrary("Workflow"),
16+
.singleTargetLibrary("WorkflowTesting"),
2317

2418
// MARK: WorkflowUI
2519

26-
.library(
27-
name: "WorkflowUI",
28-
targets: ["WorkflowUI"]
29-
),
30-
.library(
31-
name: "WorkflowSwiftUI",
32-
targets: ["WorkflowSwiftUI"]
33-
),
20+
.singleTargetLibrary("WorkflowUI"),
21+
.singleTargetLibrary("WorkflowSwiftUI"),
3422

3523
// MARK: WorkflowReactiveSwift
3624

37-
.library(
38-
name: "WorkflowReactiveSwift",
39-
targets: ["WorkflowReactiveSwift"]
40-
),
41-
.library(
42-
name: "WorkflowReactiveSwiftTesting",
43-
targets: ["WorkflowReactiveSwiftTesting"]
44-
),
25+
.singleTargetLibrary("WorkflowReactiveSwift"),
26+
.singleTargetLibrary("WorkflowReactiveSwiftTesting"),
4527

4628
// MARK: WorkflowRxSwift
4729

48-
.library(
49-
name: "WorkflowRxSwift",
50-
targets: ["WorkflowRxSwift"]
51-
),
52-
.library(
53-
name: "WorkflowRxSwiftTesting",
54-
targets: ["WorkflowRxSwiftTesting"]
55-
),
30+
.singleTargetLibrary("WorkflowRxSwift"),
31+
.singleTargetLibrary("WorkflowRxSwiftTesting"),
5632

5733
// MARK: WorkflowCombine
5834

59-
.library(
60-
name: "WorkflowCombine",
61-
targets: ["WorkflowCombine"]
62-
),
63-
.library(
64-
name: "WorkflowCombineTesting",
65-
targets: ["WorkflowCombineTesting"]
66-
),
35+
.singleTargetLibrary("WorkflowCombine"),
36+
.singleTargetLibrary("WorkflowCombineTesting"),
6737

6838
// MARK: WorkflowConcurrency
6939

70-
.library(
71-
name: "WorkflowConcurrency",
72-
targets: ["WorkflowConcurrency"]
73-
),
74-
.library(
75-
name: "WorkflowConcurrencyTesting",
76-
targets: ["WorkflowConcurrencyTesting"]
77-
),
40+
.singleTargetLibrary("WorkflowConcurrency"),
41+
.singleTargetLibrary("WorkflowConcurrencyTesting"),
7842

7943
// MARK: ViewEnvironment
8044

81-
.library(
82-
name: "ViewEnvironment",
83-
targets: ["ViewEnvironment"]
84-
),
45+
.singleTargetLibrary("ViewEnvironment"),
8546

8647
// MARK: ViewEnvironmentUI
8748

88-
.library(
89-
name: "ViewEnvironmentUI",
90-
targets: ["ViewEnvironmentUI"]
91-
),
49+
.singleTargetLibrary("ViewEnvironmentUI"),
9250
],
9351
dependencies: [
9452
.package(url: "https://github.com/ReactiveCocoa/ReactiveSwift.git", from: "7.1.1"),
95-
.package(url: "https://github.com/ReactiveX/RxSwift.git", from: "6.2.0"),
53+
.package(url: "https://github.com/ReactiveX/RxSwift.git", from: "6.6.0"),
9654
.package(url: "https://github.com/nicklockwood/SwiftFormat", exact: "0.44.14"),
9755
],
9856
targets: [
@@ -246,3 +204,13 @@ let package = Package(
246204
],
247205
swiftLanguageVersions: [.v5]
248206
)
207+
208+
// MARK: Helpers
209+
210+
extension PackageDescription.Product {
211+
static func singleTargetLibrary(
212+
_ name: String
213+
) -> PackageDescription.Product {
214+
.library(name: name, targets: [name])
215+
}
216+
}

Diff for: ViewEnvironmentUI/Sources/ViewEnvironmentPropagating.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,11 @@ public final class ViewEnvironmentUpdateObservationLifetime {
401401
}
402402

403403
private enum ViewEnvironmentPropagatingNSObjectAssociatedKeys {
404-
static var needsEnvironmentUpdate = NSObject()
405-
static var needsUpdateObservers = NSObject()
406-
static var ancestorOverride = NSObject()
407-
static var descendantsOverride = NSObject()
408-
static var customizations = NSObject()
404+
static var needsEnvironmentUpdate: UInt8 = 0
405+
static var needsUpdateObservers: UInt8 = 0
406+
static var ancestorOverride: UInt8 = 0
407+
static var descendantsOverride: UInt8 = 0
408+
static var customizations: UInt8 = 0
409409
}
410410

411411
extension ViewEnvironmentPropagating {

Diff for: WorkflowReactiveSwift.podspec

+4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ Pod::Spec.new do |s|
2020

2121
s.dependency 'Workflow', "#{s.version}"
2222

23+
s.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }
24+
2325
s.test_spec 'Tests' do |test_spec|
2426
test_spec.source_files = 'WorkflowReactiveSwift/Tests/**/*.swift'
2527
test_spec.framework = 'XCTest'
2628
test_spec.library = 'swiftos'
2729
test_spec.dependency 'WorkflowTesting', "#{s.version}"
30+
31+
test_spec.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'NO' }
2832
end
2933
end

Diff for: WorkflowReactiveSwift/Testing/SignalProducerWorkflowTesting.swift

+5-21
Original file line numberDiff line numberDiff line change
@@ -21,43 +21,27 @@ import XCTest
2121
@testable import WorkflowReactiveSwift
2222

2323
extension RenderTester {
24-
/// Expect a `SignalProducer`.
24+
/// Expect a `SignalProducer` with an optional output.
2525
///
2626
/// `SignalProducerWorkflow` is used to subscribe to `SignalProducer`s and `Signal`s.
2727
///
2828
/// ⚠️ N.B. If you are testing a case in which multiple `SignalProducerWorkflow`s are expected, **only one of them** may have a non-nil `producingOutput` parameter.
2929
///
3030
/// - Parameters:
31+
/// - outputType: The `OutputType` of the expected `SignalProducerWorkflow`. Typically this will be correctly inferred by the type system, but may need to be explicitly specified if particular optionality is desired.
3132
/// - producingOutput: An output that should be returned when this worker is requested, if any.
3233
/// - key: Key to expect this `Workflow` to be rendered with.
3334
public func expectSignalProducer<OutputType>(
34-
producingOutput output: OutputType? = nil,
35-
key: String = "",
36-
file: StaticString = #file, line: UInt = #line
37-
) -> RenderTester<WorkflowType> {
38-
expectWorkflow(
39-
type: SignalProducerWorkflow<OutputType>.self,
40-
key: key,
41-
producingRendering: (),
42-
producingOutput: output,
43-
assertions: { _ in }
44-
)
45-
}
46-
47-
/// Expect a `SignalProducer` with the specified `outputType` that produces no `Output`.
48-
///
49-
/// - Parameters:
50-
/// - outputType: The `OutputType` of the expected `SignalProducerWorkflow`.
51-
/// - key: Key to expect this `Workflow` to be rendered with.
52-
public func expectSignalProducer<OutputType>(
53-
outputType: OutputType.Type,
35+
outputType: OutputType.Type = OutputType.self,
36+
producingOutput: OutputType? = nil,
5437
key: String = "",
5538
file: StaticString = #file, line: UInt = #line
5639
) -> RenderTester<WorkflowType> {
5740
expectWorkflow(
5841
type: SignalProducerWorkflow<OutputType>.self,
5942
key: key,
6043
producingRendering: (),
44+
producingOutput: producingOutput,
6145
assertions: { _ in }
6246
)
6347
}

Diff for: WorkflowReactiveSwift/TestingTests/SignalProducerTests.swift

+22
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ class SignalProducerTests: XCTestCase {
5050
.render {}
5151
}
5252

53+
func test_signalProducerWorkflow_optionalOutput() {
54+
OptionalOutputWorkflow()
55+
.renderTester()
56+
.expectSignalProducer(
57+
outputType: Int?.self, // comment this out & test fails
58+
producingOutput: nil as Int?
59+
)
60+
.render {}
61+
}
62+
5363
private struct TestWorkflow: Workflow {
5464
typealias State = Void
5565
typealias Rendering = Void
@@ -64,4 +74,16 @@ class SignalProducerTests: XCTestCase {
6474
}
6575
}
6676
}
77+
78+
private struct OptionalOutputWorkflow: Workflow {
79+
typealias State = Void
80+
typealias Rendering = Void
81+
typealias Output = Int?
82+
83+
func render(state: State, context: RenderContext<Self>) -> Rendering {
84+
SignalProducer(value: Int?.some(1))
85+
.mapOutput { _ in AnyWorkflowAction<Self>.noAction }
86+
.rendered(in: context)
87+
}
88+
}
6789
}

Diff for: WorkflowRxSwift.podspec

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@ Pod::Spec.new do |s|
1919
s.source_files = 'WorkflowRxSwift/Sources/**/*.swift'
2020

2121
s.dependency 'Workflow', "#{s.version}"
22-
s.dependency 'RxSwift', '~> 6.2'
22+
s.dependency 'RxSwift', '~> 6.6'
2323

24-
# https://github.com/ReactiveX/RxSwift/pull/2475
25-
# s.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }
24+
s.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }
2625

2726
s.test_spec 'Tests' do |test_spec|
2827
test_spec.source_files = 'WorkflowRxSwift/Tests/**/*.swift'
2928
test_spec.framework = 'XCTest'
3029
test_spec.library = 'swiftos'
3130
test_spec.dependency 'WorkflowTesting', "#{s.version}"
3231
test_spec.dependency 'WorkflowReactiveSwift', "#{s.version}"
32+
33+
test_spec.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'NO' }
3334
end
3435
end

Diff for: WorkflowRxSwift/Testing/ObservableTesting.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ extension RenderTester {
2424
/// Expect the given worker. It will be checked for `isEquivalent(to:)` with the requested worker.
2525

2626
/// - Parameters:
27-
/// - worker: The worker to be expected
28-
/// - output: An output that should be returned when this worker is requested, if any.
27+
/// - outputType: The `OutputType` of the expected `ObservableWorkflow`.
28+
/// - producingOutput: An output that should be returned when this worker is requested, if any.
29+
/// - key: Key to expect this `Workflow` to be rendered with.
2930
public func expectObservable<OutputType>(
31+
outputType: OutputType.Type = OutputType.self,
3032
producingOutput output: OutputType? = nil,
3133
key: String = "",
3234
file: StaticString = #file, line: UInt = #line

Diff for: WorkflowRxSwift/TestingTests/ObservableTests.swift

+25-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,18 @@ class ObservableTests: XCTestCase {
2828
.render {}
2929
}
3030

31-
struct TestWorkflow: Workflow {
31+
func test_observableWorkflow_optionalOutputType() {
32+
OptionalOutputWorkflow()
33+
.renderTester()
34+
.expectObservable(
35+
outputType: Int?.self, // comment this out & test fails
36+
producingOutput: nil as Int?,
37+
key: "123"
38+
)
39+
.render {}
40+
}
41+
42+
private struct TestWorkflow: Workflow {
3243
typealias State = Void
3344
typealias Rendering = Void
3445

@@ -38,4 +49,17 @@ class ObservableTests: XCTestCase {
3849
.running(in: context, key: "123")
3950
}
4051
}
52+
53+
private struct OptionalOutputWorkflow: Workflow {
54+
typealias State = Void
55+
typealias Rendering = Void
56+
typealias Output = Int?
57+
58+
func render(state: State, context: RenderContext<Self>) -> Rendering {
59+
Observable.from([1])
60+
.map { Int?.some($0) }
61+
.mapOutput { _ in AnyWorkflowAction<Self>.noAction }
62+
.rendered(in: context, key: "123")
63+
}
64+
}
4165
}

Diff for: WorkflowRxSwiftTesting.podspec

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ Pod::Spec.new do |s|
2121
s.dependency 'Workflow', "#{s.version}"
2222
s.dependency 'WorkflowRxSwift', "#{s.version}"
2323
s.dependency 'WorkflowTesting', "#{s.version}"
24-
s.dependency 'RxSwift'
2524

2625
s.framework = 'XCTest'
2726

Diff for: WorkflowSwiftUIExperimental.podspec

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
require_relative('version')
2+
3+
Pod::Spec.new do |s|
4+
s.name = 'WorkflowSwiftUIExperimental'
5+
s.version = '0.1'
6+
s.summary = 'Infrastructure for Workflow-powered SwiftUI'
7+
s.homepage = 'https://www.github.com/square/workflow-swift'
8+
s.license = 'Apache License, Version 2.0'
9+
s.author = 'Square'
10+
s.source = { :git => 'https://github.com/square/workflow-swift.git', :tag => "swiftui-experimental/v#{s.version}" }
11+
12+
# 1.7 is needed for `swift_versions` support
13+
s.cocoapods_version = '>= 1.7.0'
14+
15+
s.swift_versions = [WORKFLOW_SWIFT_VERSION]
16+
s.ios.deployment_target = WORKFLOW_IOS_DEPLOYMENT_TARGET
17+
s.osx.deployment_target = WORKFLOW_MACOS_DEPLOYMENT_TARGET
18+
19+
s.source_files = 'WorkflowSwiftUIExperimental/Sources/*.swift'
20+
21+
s.dependency 'Workflow', WORKFLOW_VERSION
22+
s.dependency 'WorkflowUI', WORKFLOW_VERSION
23+
24+
s.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }
25+
end

Diff for: WorkflowSwiftUIExperimental/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# WorkflowSwiftUIExperimental
2+
3+
Experimental extensions to Workflow for writing Screens in SwiftUI.
4+
5+
## Versioning
6+
7+
Because this module is experimental, it is versioned separately from other modules in Workflow. You should bump its version as part of any pull request that changes it, and need not bump its version in PRs that change only other modules.
8+
9+
Per semantic versioning, its major version remains at `0`, and only its minor version is incremented. Any increase in the minor version may come with breaking changes.
10+
11+
To bump the minor version, update `s.version` in `WorkflowSwiftUIExperimental.podspec`.

0 commit comments

Comments
 (0)