• Stars
    star
    2,515
  • Rank 17,564 (Top 0.4 %)
  • Language
    Swift
  • License
    Other
  • Created about 3 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Open source game built in SwiftUI and the Composable Architecture.

isowords

CI

This repo contains the full source code for isowords, an iOS word search game played on a vanishing cube. Connect touching letters to form words, the longer the better, and the third time a letter is used its cube is removed, revealing more letters inside!

Available on the App Store now!

Download isowords on the App Store

isowords screenshots


About

isowords is a large, complex application built entirely in Swift. The iOS client's logic is built in the Composable Architecture and the UI is built mostly in SwiftUI with a little bit in SceneKit. The server is also built in Swift using our experimental web server libraries.

We published a 4-part series of videos covering these topics and more on Point-Free, a video series exploring functional programming and the Swift language, hosted by Brandon Williams and Stephen Celis.

video poster image



Some things you might find interesting:

The Composable Architecture

The whole application is powered by the Composable Architecture, a library we built from scratch on Point-Free that provides tools for building applications with a focus on composability, modularity, and testability. This means:

  • The entire app's state is held in a single source of truth, called a Store.
  • The entire app's behavior is implemented by a single unit, called a Reducer, which is composed out of many other reducers.
  • All effectful operations are made explicit as values returned from reducers.
  • Dependencies are made explicit as simple data types wrapping their live implementations, along with various mock instances.

There are a ton of benefits to designing applications in this manner:

  • Large, complex features can be broken down into smaller child domains, and those domains can communicate via simple state mutations. Typically this is done in SwiftUI by accessing singletons inside ObservableObject instances, but this is not necessary in the Composable Architecture.
  • We take control of dependencies rather than allow them to take control of us. Just because you are using StoreKit, GameCenter, UserNotifications, or any other 3rd party APIs in your code, it doesn't mean you should sacrifice your ability to run your app in the simulator, SwiftUI previews, or write concise tests.
  • Exhaustive tests can be written very quickly. We test very detailed user flows, capture subtle edge cases, and assert on how effects execute and how their outputs feed back into the application.
  • It is straightforward to write integration tests that exercise multiple independent parts of the application.

Hyper-modularization

The application is built in a hyper-modularized style. At the time of writing this README the client and server are split into 86 modules. This allows us to work on features without building the entire application, which improves compile times and SwiftUI preview stability. It also made it easy for us to ship an App Clip, whose size must be less than 10 MB uncompressed, by choosing the bare minimum of code and resources to build.

Client/Server monorepo

The code for both the iOS client and server are included in this single repository. This makes it easy to run both the client and server at the same time, and we can even debug them at the same time, e.g. set breakpoints in the server that are triggered when the simulator makes API requests.

We also share a lot of code between client and server:

  • The core types that describe players, puzzles, moves, etc.
  • Game logic, such as the random puzzle generator, puzzle verification, dictionaries, and more.
  • The router used for handling requests on the server is the exact same code the iOS client uses to make API requests to the server. New routes only have to be specified a single time and it is immediately available to both client and server.
  • We write integration tests that simultaneously test the server and iOS client. During a test, API requests made by the client are actually running real server code under the hood.
  • And more...

Automated App Store screenshots and previews

The screenshots and preview video that we upload to the App Store for this app are automatically generated.

  • The screenshots are generated by a test suite using our SnapshotTesting library, and do the work of constructing a very specific piece of state that we load into a screen, as well as framing the UI and providing the surrounding graphics.

  • The preview video is generated as a screen recording of running a slimmed-down version of the app that embeds specific letters onto a cube and runs a sequence of actions to emulate a user playing the game. The app can be run locally by selecting the TrailerPreview target in Xcode and running it in the simulator.

Preview apps

There are times that we want to test a feature in isolation without building the entire app. SwiftUI previews are great for this but they also have their limitations, such as if you need to use APIs unavailable to previews, or if you need to debug more complex flows, etc.

So, we create mini-applications that build a small subset of the 86+ modules that comprise the entire application. Setting up these applications requires minimal work. You just specify what dependencies you need in the Xcode project and then create an entry point to launch the feature.

For example, here is all the code necessary to create a preview app for running the onboarding flow in isolation. If we were at the whims of the full application to test this feature we would need to constantly delete and reinstall the app since this screen is only shown on first launch.

Getting Started

This repo contains both the client and server code for running the entire isowords application, as well as an extensive test suite. To get things running:

  1. Make sure git-lfs is installed so that app assets (images, etc.) can be fetched. For example, with Homebrew:

    $ brew install git-lfs  # Download and install Git LFS
    $ git lfs install       # Set up Git LFS for your user
  2. Grab the code:

    git clone https://github.com/pointfreeco/isowords
    cd isowords
  3. Bootstrap the application:

    1. If you are only interested in building the iOS client, then run the following bootstrap command:
      make bootstrap-client
    2. If you want to build the client and server make sure PostgreSQL is installed and running, and then run the following bootstrap command:
      make bootstrap
  4. Open the Xcode project App/isowords.xcodeproj.

  5. To run the client locally, select the isowords target in Xcode and run (โŒ˜R).

  6. To run the server locally, select the server target in Xcode and run (โŒ˜R).

Learn More

Most of the concepts discussed in this README are covered in-depth on Point-Free, a video series exploring functional programming and the Swift language, hosted by Brandon Williams and Stephen Celis.

Point-Free

Related Projects

This application makes use of a number of open source projects built by us and discussed on Point-Free, including:

License

The source code in this repository may be run and altered for education purposes only and not for commercial purposes. For more information see our full license.

More Repositories

1

swift-composable-architecture

A library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind.
Swift
10,990
star
2

swift-snapshot-testing

๐Ÿ“ธ Delightful Swift snapshot testing.
Swift
3,559
star
3

swiftui-navigation

Tools for making SwiftUI navigation simpler, more ergonomic and more precise.
Swift
1,654
star
4

swift-dependencies

A dependency management library inspired by SwiftUI's "environment."
Swift
1,322
star
5

swift-tagged

๐Ÿท A wrapper type for safer, expressive code.
Swift
1,289
star
6

swift-overture

๐ŸŽผ A library for function composition.
Swift
1,115
star
7

pointfreeco

๐ŸŽฌ The source for www.pointfree.co, a video series on functional programming and the Swift programming language.
Swift
1,054
star
8

episode-code-samples

๐Ÿ’พ Point-Free episode code.
Swift
922
star
9

swift-case-paths

๐Ÿงฐ Case paths extends the key path hierarchy to enum cases.
Swift
852
star
10

swift-nonempty

๐ŸŽ A compile-time guarantee that a collection contains a value.
Swift
817
star
11

swift-parsing

A library for turning nebulous data into well-structured data, with a focus on composition, performance, generality, and ergonomics.
Swift
802
star
12

swift-custom-dump

A collection of tools for debugging, diffing, and testing your application's data structures.
Swift
766
star
13

swift-html

๐Ÿ—บ A Swift DSL for type-safe, extensible, and transformable HTML documents.
Swift
726
star
14

combine-schedulers

โฐ A few schedulers that make working with Combine more testable and more versatile.
Swift
671
star
15

swift-web

๐Ÿ•ธ A collection of Swift server-side frameworks for handling HTML, CSS, routing and middleware.
Swift
477
star
16

swift-identified-collections

A library of data structures for working with collections of identifiable elements in an ergonomic, performant way.
Swift
476
star
17

swift-prelude

๐ŸŽถ A collection of types and functions that enhance the Swift language.
Swift
456
star
18

swift-perception

Observable tools, backported.
Swift
399
star
19

swift-validated

๐Ÿ›‚ A result type that accumulates multiple errors.
Swift
389
star
20

swift-url-routing

A bidirectional router with more type safety and less fuss.
Swift
321
star
21

swift-concurrency-extras

Useful, testable Swift concurrency.
Swift
267
star
22

swift-gen

๐ŸŽฑ Composable, transformable, controllable randomness.
Swift
262
star
23

swift-clocks

โฐ A few clocks that make working with Swift concurrency more testable and more versatile.
Swift
229
star
24

swift-enum-properties

๐Ÿค Struct and enum data access in harmony.
Swift
198
star
25

xctest-dynamic-overlay

Define XCTest assertion helpers directly in your application and library code.
Swift
197
star
26

swift-macro-testing

Magical testing tools for Swift macros.
Swift
192
star
27

syncups

A rebuild of Appleโ€™s โ€œScrumdingerโ€ application using modern, best practices for SwiftUI development.
Swift
153
star
28

composable-core-location

A library that bridges the Composable Architecture and Core Location.
Swift
100
star
29

vapor-routing

A bidirectional Vapor router with more type safety and less fuss.
Swift
83
star
30

swift-html-vapor

๐Ÿ’ง Vapor plugin for type-safe, transformable HTML views.
Swift
82
star
31

swift-playground-templates

๐Ÿซ A collection of helpful Xcode playground templates.
Makefile
80
star
32

pointfreeco-server

Point-Free server code.
39
star
33

swift-boundaries

๐Ÿฃ Functional core, imperative shell.
Swift
27
star
34

composable-core-motion

A library that bridges the Composable Architecture and Core Motion.
Swift
26
star
35

swift-quickcheck

๐Ÿ An implementation of QuickCheck in Swift.
Swift
24
star
36

swift-algebras

Algebraic laws bundled into concrete data types.
19
star
37

swift-either

For those times you want A or B!
Swift
19
star
38

swift-parser-printer

โ†”๏ธ Parsing and printing
Swift
14
star
39

swift-html-kitura

โ˜๏ธ Kitura plugin for type-safe, transformable HTML views.
Swift
13
star
40

homebrew-swift

Ruby
2
star
41

swift-bugs

2
star
42

Ccmark

Swift
1
star