Skip to content

Commit

Permalink
feat: Move to tuist as a project generation tool
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderwe authored Dec 6, 2020
2 parents c8dc127 + 616cc2f commit 2239adb
Show file tree
Hide file tree
Showing 74 changed files with 396 additions and 1,448 deletions.
35 changes: 17 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# iOS-Starter

![version](https://img.shields.io/badge/version-v0.5.1-green)
![version](https://img.shields.io/badge/version-v1.0.0-green)

This is a template project for boostrapping iOS applications

## Prequisites

Install [cookiecutter](https://cookiecutter.readthedocs.io/en/latest/index.html),[XcodeGen](https://github.com/yonaskolb/XcodeGen) and [Mint](https://github.com/yonaskolb/Mint) in order to create a new project from this template:
Install [cookiecutter](https://cookiecutter.readthedocs.io/en/latest/index.html),[tuist](https://github.com/tuist/tuist) and [Mint](https://github.com/yonaskolb/Mint) in order to create a new project from this template:

```sh
brew install cookiecutter
brew install xcodegen
bash <(curl -Ls https://install.tuist.io)
brew install mint
```

Expand All @@ -25,7 +25,7 @@ cookiecutter https://github.com/alexanderwe/ios-starter.git
- Apple Developer Team details
- other details necessary for the project
- `cookiecutter` will create all necessary files
- `XcodeGen` runs and automatically creates a `.xcodeproj` file
- `tuist` runs and automatically creates a `.xcodeproj` file
- Afterwards `mint bootstratp` will run to download all necessary build tools
- Finally `Xcode` will launch your new project
- All code dependencies are managed with the `Swift Package Manager`
Expand All @@ -36,45 +36,44 @@ cookiecutter https://github.com/alexanderwe/ios-starter.git
- Logging Helper
- [LoggingKit](https://github.com/alexanderwe/LoggingKit) - A small micro-framework for logging
- Code Style
- [SwiftLint](https://www.github.com/realm/SwiftLint) - Common linting rules
- Helpers
- [Rswift](https://github.com/mac-cain13/R.swift) - Type safe access to string resources
- [swiftformat](https://github.com/nicklockwood/SwiftFormat) - Format and lint your source code


## Structure

The structure of the template project tries to follow the idea in [this article](https://theswiftdev.com/2016/07/06/conventions-for-xcode/) from `The.Swift.Dev`
The structure of the template project tries to follow the idea of having a directory for each of your target. In each of these targets you can find it sources and the corresponding tests.

External dependencies are managed via `Swift Package Manager`. Therefore it is mandatory to use **Xcode 11**.

### External build tools

External build tools like `swiftlint` and `R.swift` are managed by `Mint` This is necessary because the `Swift Package Manager` is not handling binaries, and therefore `Mint` is doing this job for us.
External build tools like `swiftformat` are managed by `Mint`.

### Modules

The project is divided into several modules:

- `iOSApplication` - Contains UI code, navigation flows, views if used for SwiftUI or view controllers when UIKit is used
- `iOSApplicationTests` - Unit tests for the iOS application
- `iOSApplicationUITests` - UI tests for the iOS application
- `iOS` - Contains UI code, navigation flows, views if used for SwiftUI or view controllers when UIKit is used
- `Tests iOS` - Unit tests for the iOS application
- `UI Tests iOS` - UI tests for the iOS application
- `<ProjectName>Kit` - Source files for your service layer or generally speaking files that could be reused for example for an macOS or watchOS target
- `<ProjectName>KitTests` - Unit test for the `<ProjectName>Kit` target
- `<ProjectName>Kit Tests` - Unit test for the `<ProjectName>Kit` target

### Schemes

In general each target has its own scheme but the `iOSApplication` target has three:
In general each target has its own scheme but the `iOS` target has three:

- development
- staging
- production

Each scheme is used in combination with the files located in `iOSApplication/SupportingFiles/Config`. There you can find four different files. Three for each scheme and one which contains the values for the active configuration. Each scheme has a `pre-build` action which copies the content from one of "release type" configs to `Configuration.xcconfig` which is then used when the app is running.
Each scheme is used in combination with the files located in `Targets/iOS/SupportingFiles/Config`. There you can find four different files. Three for each scheme and one which contains the values for the active configuration. Each scheme has a `pre-build` action which copies the content from one of "release type" configs to `Configuration.xcconfig` which is then used when the app is running.

So for example if you are running the `iOS Applcation staging` scheme, the content of the `Staging.xcconfig` file is copied over to `Configuration.xcconfig` and can then be used within the app.

Currently this mechanism is used to change the app identifier and set some environment variable. This can be extended to for example use different backend urls for different schemes.

If you want to access one of the variables you declare inside the `.xcconfig` files you need to make them accessible to the app by putting them into the `iOSApplication/Sources/SupportingFiles/Info.plist` file. As an example you can have a look at the `_ServerEnvironment` variable which is later accessed within the `ViewController`.
If you want to access one of the variables you declare inside the `.xcconfig` files you need to make them accessible to the app by putting them into the `Derived/InfoPlists/<Info.plist file for iOS target>` file. As an example you can have a look at the `_ServerEnvironment` variable which is later accessed within the `ViewController`.

#### External configuration files

Expand All @@ -88,7 +87,7 @@ The mechanism described above can also be used for external configuration files.
Inside the `pre-build` actions for the different schemes you copy the content of the corresponding file to `GoogleService-Info.plist` which is then used by your Google frameworks in the app. Such an `pre-build` command could like like the following.

```sh
cp -f "${PROJECT_DIR}/iOSApplication/SupportingFiles/Config/Firebase/GoogleService-Info.development.plist" "${PROJECT_DIR}/iOSApplication/SupportingFiles/Config/Firebase/GoogleService-Info.plist"
cp -f "${PROJECT_DIR}/Targets/iOS/SupportingFiles/Config/Firebase/GoogleService-Info.development.plist" "${PROJECT_DIR}/Targets/iOS/SupportingFiles/Config/Firebase/GoogleService-Info.plist"
```

### UIKit or SwiftUI
Expand All @@ -112,7 +111,7 @@ The template uses [fastlane](https://fastlane.tools) for CI/CD. It comes with a
Be sure to run `bundle install` first and then execute fastlane through `bundle exec`.

```sh
bundle exec fastlane run tests
bundle exec fastlane tests
```

### Included Actions
Expand Down
6 changes: 2 additions & 4 deletions cookiecutter.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
{
"projectName": "Example",
"projectDirectory": "{{cookiecutter.projectName|lower|replace(' ', '-')}}-ios",
"projectDirectory": "{{cookiecutter.projectName|lower|replace(' ', '-')}}",
"teamId": "TeamID",
"teamName": "TeamName",
"companyName": "CompanyName",
"bundleIdentifier": "com.example.{{cookiecutter.projectName|lower|replace(' ', '-')}}",
"deploymentTarget": "13.0",
"runMintBootstrap": "y",
"runXcodeGen": "y",
"deploymentTarget": "14.0",
"gitRepository": "https://github.com/alexanderwe/ios-starter.git",
"_copy_without_render": [
"*.tpl.md"
Expand Down
19 changes: 5 additions & 14 deletions hooks/post_gen_project.sh
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
#! /bin/bash

# Run xcodegen to create .xcodeproj file
{%- if cookiecutter.runXcodeGen == 'y' %}
xcodegen
{%- endif %}

# Install Mint dependecies
{%- if cookiecutter.runMintBootstrap == 'y' %}
mint bootstrap
{%- endif %}

# If xcodegen has generated a .xcodeproj file we want to open it
{%- if cookiecutter.runXcodeGen == 'y' %}
xed .
{%- endif %}
# Run tuist to create .xcodeproj file
tuist generate

# Set up git
git init

# If tuist has generated a .xcodeproj file we want to open it
xed .

## Configure git hooks
chmod +x ./.githooks/commit-msg
git config core.hooksPath .githooks
Expand Down
113 changes: 18 additions & 95 deletions {{cookiecutter.projectDirectory}}/.gitignore
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
# Custom ignores

*.generated.swift



# Created by https://www.gitignore.io/api/xcode,swift,macos,swiftpm,cocoapods,swiftpackagemanager
# Edit at https://www.gitignore.io/?templates=xcode,swift,macos,swiftpm,cocoapods,swiftpackagemanager

### CocoaPods ###
## CocoaPods GitIgnore Template

# CocoaPods - Only use to conserve bandwidth / Save time on Pushing
# - Also handy if you have a large number of dependant pods
# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE
Pods/

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
# Icon must end with two
Icon

# Thumbnails
Expand All @@ -43,16 +26,22 @@ Network Trash Folder
Temporary Items
.apdisk

### Swift ###
### Xcode ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
## User settings
xcuserdata/

## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout

## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/

## Various settings
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
Expand All @@ -61,84 +50,18 @@ DerivedData/
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/

## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint

## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
.build/

# CocoaPods
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
# Pods/
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace

# Carthage
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build

# Accio dependency management
Dependencies/
.accio/

# fastlane
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

# Code Injection
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode

iOSInjectionProject/

### Xcode ###
# Xcode
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## User settings

## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)

## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)

## Xcode Patch
### Xcode Patch ###
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/
!*.xcworkspace/contents.xcworkspacedata
/*.gcno

### Xcode Patch ###
**/xcshareddata/WorkspaceSettings.xcsettings

# End of https://www.gitignore.io/api/xcode,swift,macos,swiftpm,cocoapods,swiftpackagemanager
### Projects ###
*.xcodeproj
*.xcworkspace

### Tuist derived files ###
graph.dot
Derived/
2 changes: 2 additions & 0 deletions {{cookiecutter.projectDirectory}}/.swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

5.3
16 changes: 16 additions & 0 deletions {{cookiecutter.projectDirectory}}/.swiftformat
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# format options
--indent tab
--tabwidth 4

# Enabled rules
--rules duplicateImports
--rules elseOnSameLine
--rules emptyBraces
--rules hoistPatternLet
--rules redundantParens


# Disabled rules
--disable indent #Rationale: Until decided, too many false positives
--disable redundantType #Rationale: Sometimes it makes the code easier to understand to explicitly declare the type, even if its obvious for the compiler
--disable redundantReturn #Rationale: Omitting the `return` keyword is a new feature in Swift 5.3. It could be confusing for new developers to omit it
Loading

0 comments on commit 2239adb

Please sign in to comment.