Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions ViewEnvironmentUI/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# ViewEnvironmentUI

`ViewEnvironmentUI` provides a means to propagate a `ViewEnvironment` through a hierarchy of object nodes.

Support for propagation of `ViewEnvironment` through `UIViewController`s and `UIView`s is provided by this framework.
`ViewEnvironmentUI` provides some fundamental types to build UI:

- A means to propagate a `ViewEnvironment` through a hierarchy of object nodes, and an implementation of propagation through `UIViewController`s and `UIView`s.
- The `ViewDescription` type, a declarative way to represent a view controller.
- The `Screen` protocol, to create your own types that can produce a `ViewDescription` from a `ViewEnvironment`.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#if canImport(UIKit)

import UIKit
import ViewEnvironment

public struct AnyScreen: Screen {
/// The original screen, retained for debugging
Expand All @@ -42,12 +43,4 @@ extension Screen {
}
}

// MARK: SingleScreenContaining

extension AnyScreen: SingleScreenContaining {
public var primaryScreen: any Screen {
wrappedScreen
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#if canImport(UIKit)

import UIKit
import ViewEnvironment

/// Screens are the building blocks of an interactive application.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#if canImport(UIKit)

import UIKit
import ViewEnvironment

extension UpdateChildScreenViewController where Self: UIViewController {
/// Updates the view controller at the given `child` key path with the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import UIKit
import ViewEnvironment
@_spi(ViewEnvironmentWiring) import ViewEnvironmentUI

/// A ViewControllerDescription acts as a "recipe" for building and updating a specific `UIViewController`.
/// It describes how to _create_ and later _update_ a given view controller instance, without creating one
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
#if canImport(UIKit)

import UIKit
import ViewEnvironment
import ViewEnvironmentUI
import XCTest
@testable import WorkflowUI

class AdaptedEnvironmentScreenTests: XCTestCase {
func test_wrapping() {
Expand Down Expand Up @@ -53,10 +54,12 @@ fileprivate struct TestScreen: Screen {
func viewControllerDescription(environment: ViewEnvironment) -> ViewControllerDescription {
read(environment)

return ViewController.description(for: self, environment: environment)
return ViewControllerDescription(
environment: environment,
build: UIViewController.init,
update: { _ in }
)
}

private class ViewController: ScreenViewController<TestScreen> {}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
#if canImport(UIKit)

import UIKit
import ViewEnvironment
import ViewEnvironmentUI
import XCTest
@testable import WorkflowUI

class UIViewControllerExtensionTests: XCTestCase {
func test_update_viewNotLoaded() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@

#if canImport(UIKit)

import ViewEnvironment
import ViewEnvironmentUI
import XCTest

import ReactiveSwift
import Workflow
@testable import WorkflowUI

fileprivate class BlankViewController: UIViewController {}

@objc fileprivate protocol MyProtocol {
Expand Down Expand Up @@ -179,30 +177,6 @@ class ViewControllerDescriptionTests: XCTestCase {
XCTAssertEqual(environment[TestKey.self], 2)
}
}

func test_screenViewController() {
// Make sure ScreenViewController<T>.description(for:) generates a correct view controller
// description

struct MyScreen: Screen {
func viewControllerDescription(environment: ViewEnvironment) -> ViewControllerDescription {
MyScreenViewController.description(for: self, environment: environment)
}
}

final class MyScreenViewController: ScreenViewController<MyScreen> {}

let screen = MyScreen()
let description = screen.viewControllerDescription(environment: .empty)

let viewController = description.buildViewController()
XCTAssertTrue(type(of: viewController) == MyScreenViewController.self)

XCTAssertTrue(description.canUpdate(viewController: viewController))

let viewControllerAgain = description.buildViewController()
XCTAssertFalse(viewController === viewControllerAgain)
}
}

class ViewControllerDescription_KindIdentifierTests: XCTestCase {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2020 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#if canImport(UIKit)

extension AnyScreen: SingleScreenContaining {
public var primaryScreen: any Screen {
wrappedScreen
}
}

#endif
33 changes: 33 additions & 0 deletions WorkflowUI/Tests/ScreenViewControllerTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#if canImport(UIKit)

import UIKit
import WorkflowUI
import XCTest

final class ScreenViewControllerTests: XCTestCase {
func test_screenViewController() {
// Make sure ScreenViewController<T>.description(for:) generates a correct view controller
// description

struct MyScreen: Screen {
func viewControllerDescription(environment: ViewEnvironment) -> ViewControllerDescription {
MyScreenViewController.description(for: self, environment: environment)
}
}

final class MyScreenViewController: ScreenViewController<MyScreen> {}

let screen = MyScreen()
let description = screen.viewControllerDescription(environment: .empty)

let viewController = description.buildViewController()
XCTAssertTrue(type(of: viewController) == MyScreenViewController.self)

XCTAssertTrue(description.canUpdate(viewController: viewController))

let viewControllerAgain = description.buildViewController()
XCTAssertFalse(viewController === viewControllerAgain)
}
}

#endif
Loading