playbook-ios
Playbook is a library that provides a sandbox for building UI components without having to worry about application-specific dependencies, strongly inspired by Storybook for JavaScript in web-frontend development.
Components built using Playbook can generates a standalone app as living style guide.
This not only allows quick UI confirmation but also facilitates business logic separation and deliver more robust designs.
Besides, snapshots of each component can be automatically generated by unit tests, and visual regression tests can be performed using arbitrary third-party tools.
For complex modern app development, it’s important to catch UI changes more sensitively and keep improving them faster.
With the Playbook, you don't have to struggle through preparing the data and also spend human resources on elaborate manual testing.
Usage
Playbook
Playbook
is a framework that provides the basic functionality for managing components and supports both SwiftUI
and UIKit
.
Components are uniquely stored as scenarios. A Scenario
has the way to layout component.Please check the API Doc for the variety of layouts.
Playbook.default.addScenarios(of: "Home") {
Scenario("CategoryHome", layout: .fill) {
CategoryHome().environmentObject(UserData.stub)
}
Scenario("LandmarkList", layout: .fill) {
NavigationView {
LandmarkList().environmentObject(UserData.stub)
}
}
Scenario("UIView red", layout: .fixed(length: 100)) {
let view = UIView()
view.backgroundColor = .red
return view
}
}
ScenarioProvider
allows you to isolate additional scenarios and keep your playbook building clean.
struct HomeScenarios: ScenarioProvider {
static func addScenarios(into playbook: Playbook) {
playbook.addScenarios(of: "Home") {
Scenario("CategoryHome", layout: .fill) {
CategoryHome().environmentObject(UserData.stub)
}
}
}
}
struct AllScenarios: ScenarioProvider {
static func addScenarios(into playbook: Playbook) {
playbook.add(HomeScenarios.self)
}
}
You can use the ScenarioContext
passed to the closure that creates the component to get the screen size in snapshot, or wait before generating a snapshot.
Scenario("MapView", layout: .fill) { context in
MapView(coordinate: landmarkData[10].locationCoordinate) {
// This closure will called after the map has completed to render.
context.snapshotWaiter.fulfill()
}
.onAppear(perform: context.snapshotWaiter.wait)
}
PlaybookSnapshot
Scenarios can be tested by the instance of types conform to TestTool
protocol.
Snapshot
is one of them, which can generate the snapshots of all scenarios with simulate the screen size and safe area of the given devices.
Since Snapshot
depends on XCTest
, it should be used in the module for unit test.
final class SnapshotTests: XCTestCase {
func testTakeSnapshot() throws {
let directory = ProcessInfo.processInfo.environment["SNAPSHOT_DIR"]!
try Playbook.default.run(
Snapshot(
directory: URL(fileURLWithPath: directory),
clean: true,
format: .png,
keyWindow: UIApplication.shared.windows.first { $0.isKeyWindow },
devices: [.iPhone11Pro(.portrait)]
)
)
}
}
PlaybookUI
PlaybookUI
is a framework that provides user interfaces made by SwiftUI
for browsing a list of scenarios.
PlaybookGallery
The component visuals are listed and displayed.
Those are displayed on the top screen are not actually doing layout, but rather display the snapshots that is efficiently generated at runtime.
Browser | Detail |
---|---|
PlaybookCatalog
The UI that search and select a scenario in a drawer. It's more similar to Storybook
.
If you have too many scenarios, this may be more efficient than PlaybookCatalog
.
Browser | Detail |
---|---|
How to Save Snapshot Images
To save snapshot images to the photo library from the share button on each UI, NSPhootLibraryAddUsageDescription
must be supported. See the official document for more information.
Integration with Third-party Tools
The snapshot image files generated on the host machine's file system by PlaybookSnapshot
can be used with a variety of third-party tools.
reg-viz/reg-suit
It's highly recommended to use reg-suit
in order to sublimate the snapshot images to the visual regression test.
It sends a report of UI changes for each pull request and visually check the impact on the existing components.
See reg-viz/reg-suit for more details.
Example pull-request is here.
Requirements
- Swift 5.1+
- Xcode 11.0+
- iOS
Playbook
: 11.0+PlaybookSnapshot
: 11.0+PlaybookUI
: 13.0+
Installation
Playbook features are separated into the following frameworks.
Playbook
: Core system of component management.PlaybookSnapshot
: Generates snapshots of all components.PlaybookUI
: Products a browsing UI for components managed by Playbook.
CocoaPods
Add the following to your Podfile
:
target 'YourPlaybook' do
pod 'Playbook'
pod 'PlaybookUI'
target 'YourPlaybookTests' do
inherit! :search_paths
pod 'PlaybookSnapshot'
end
end
Carthage
Add the following to your Cartfile
:
github "playbook-ui/playbook-ios"
Swift Package Manager
Select Xcode menu File > Swift Packages > Add Package Dependency...
and enter repository URL with GUI.
Repository: https://github.com/playbook-ui/playbook-ios
Note: Currently, SwiftPM doesn't support specifying the OS version for each library, so only iOS13
is supported.