Skip to content

Commit

Permalink
Merge pull request #54 from fulldecent/master
Browse files Browse the repository at this point in the history
Update recipe and example for new Xcode
  • Loading branch information
fulldecent committed Mar 2, 2024
2 parents 9dbb723 + 0834d81 commit c47eb05
Show file tree
Hide file tree
Showing 22 changed files with 497 additions and 404 deletions.
2 changes: 1 addition & 1 deletion LICENSE
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2016 William Entriken
Copyright (c) 2016-2024 William Entriken

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
45 changes: 18 additions & 27 deletions README.md
@@ -1,41 +1,30 @@
[![Build Status](https://travis-ci.org/fulldecent/swift5-module-template.svg?branch=master)](https://travis-ci.org/fulldecent/swift5-module-template)

# Swift 5 Module Template

Use this template as a starting point for any Swift 5 module that you want other people to include in their projects.

**STATUS: This template is ready and works in production code, compatible with Xcode 13.1 (13A1030d)**
**STATUS: This template is ready and works in production code, compatible with Xcode 15.2 (15C500b)**

![Swift 5 Module directory layout](https://user-images.githubusercontent.com/382183/66881876-63cca680-ef96-11e9-9dde-ae9d5c35350c.png)

## Features
Your new Swift 5 module will immediately have working, compilable code, and all these features:

- Ability to be used from Swift Package Manager, CocoaPods and Carthage
Your new Swift 5 module will immediately have working, compilable code, and implement these best practices:

- Ability to be used from Swift Package Manager
- Clean folder structure
- MIT license
- Testing as a standard
- Turnkey access to GitHub Actions testing
- Semantic versioning and a CHANGELOG
- Included example/demo app using SwiftUI

We make the assumption you are using an Xcode project to manage your code.
- Use a Xcode project to manage your code

## How to use this

Clone or [download a release](https://github.com/fulldecent/swift5-module-template/releases) and run the `./configure` program. It will ask you some questions and generate a project.

Or if you have CocoaPods installed, you can alternatively use:

```sh
pod lib create --verbose --template-url='https://github.com/fulldecent/swift5-module-template.git' MyNewPodName
```
Clone or [download a release](https://github.com/fulldecent/swift5-module-template/releases) and run the `./configure.rb` program. It will ask you some questions and generate a project.

You then add all the interesting features you want your module to have.

### Using CocoaPods to manage dependencies for your example app

You distribute an example app with your new Swift module to show that it works. You may also decide to add UI tests to your example app and some people like to use testing frameworks for those UI tests. If you would like to use CocoaPods to manage the dependencies of your example app, please see the discussion at https://github.com/fulldecent/swift5-module-template/issues/8.

### Automating the configure script

To skip interactive prompts in the `./configure` script, use these environment variables:
Expand All @@ -55,17 +44,19 @@ For example, you may use: `export SMT_ORGANIZATION_NAME='Awesome Org'` before ru

## How it works

```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Use │ │ Save │ │Use your own │
│ Xcode │─Save recipe─▶│ template │─./configure─▶│ module │
└─────────────┘ └─────────────┘ └─────────────┘
▲ ▲ ▲ ▲ ▲
│ │ │ │ │
Contributors to this project End users of this project
```mermaid
graph LR
subgraph Contributors to this project
X[Use Xcode] --> R[Update Recipe.md]
R --> T[Update template]
end
T --> C
subgraph End users of this project
C[Run ./configure.rb] --> M[Use your own module]
end
```

## Contributing

See the file [Recipe.md](Recipe.md) for the complete steps (e.g. Open Xcode, make new project, click here, type that, …) of how we made the template.

90 changes: 41 additions & 49 deletions Recipe.md
@@ -1,13 +1,15 @@
# Recipe

This recipe documents exactly how we created the Swift 5 Module Template. Please follow along and you should create a template that is identical to the one we provided. If this recipe is not perfect (or your result is different from our template in any way) then please submit an issue or pull request.
This recipe cites all best practices we follow and documents exactly how we created the Swift 5 Module Template which is the [xxPROJECTxNAMExx folder](./xxPROJECTxNAMExx) in this repo.

This recipe may also be useful for other scenarios, for example maybe you want to make a project that has the iOS example app using storyboards instead of SwiftUI.
Please follow along and you should create a template that is identical to the one we provided. If this recipe is not perfect (or your result is different from our template in any way) then please submit an issue or pull request.

This recipe may also be useful for other scenarios, for example maybe you want to make a project that has the Example app using storyboards instead of SwiftUI.


## Ingredients

During the steps of this recipe we enter specific values where needed. These are chosen carefully so that the `./configure` script can later find and replace these values in the template to create your project.
During the steps of this recipe we enter specific values where needed. These are chosen carefully so that the `./configure.rb` script can later find and replace these values in the template to create your project.

Some variables have spaces in them. That is intentional because Xcode only uses robust quoting in its project configuration files (which we want) if the variables have spaces in them.

Expand Down Expand Up @@ -35,17 +37,18 @@ Some variables have spaces in them. That is intentional because Xcode only uses

Complete all these instructions on the same calendar day.

Use Xcode Version 13.1 (13A1030d). *This is the latest publicly released or Gold Master version.*
Use Xcode Version 15.2 (15C500b). *This is the latest publicly released or Gold Master version.*

This recipe is also demonstrated in a YouTube flyover at https://youtu.be/ksYXtNn8lhE (15 minutes).
A previous version of this recipe is also demonstrated in a YouTube flyover at https://youtu.be/ksYXtNn8lhE (15 minutes).

### I. Create a package for your module

1. In Xcode, choose File > New > Package…
1. Navigate to your Desktop folder
2. Type the name `xxPROJECTxNAMExx`
3. Ensure "Create Git repository on my Mac" is unchecked
4. Click “Create"
1. Choose Multiplatform > Library > Library, and click "Next"
2. Navigate to your Desktop folder
3. Type the name `xxPROJECTxNAMExx`
4. Ensure "Create Git repository on my Mac" is unchecked
5. Click “Create"


### II. Add some functionality to the module
Expand All @@ -54,11 +57,11 @@ This recipe is also demonstrated in a YouTube flyover at https://youtu.be/ksYXtN

```sh
cd ~/Desktop/xxPROJECTxNAMExx/Sources/xxPROJECTxNAMExx/
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/master/xxPROJECTxNAMExx/Sources/xxPROJECTxNAMExx/xxPROJECTxNAMExx.swift' -o xxPROJECTxNAMExx.swift
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/master/xxPROJECTxNAMExx/Sources/xxPROJECTxNAMExx/White%20King.swift' -o White\ King.swift
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/main/xxPROJECTxNAMExx/Sources/xxPROJECTxNAMExx/xxPROJECTxNAMExx.swift' -o xxPROJECTxNAMExx.swift
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/main/xxPROJECTxNAMExx/Sources/xxPROJECTxNAMExx/White%20King.swift' -o White\ King.swift
```

### III. Create a Swift project for your iOS Example application
### III. Create a Swift project for your Example application

1. In Xcode, choose File > New > Project…
1. *Choose a template*
Expand All @@ -67,12 +70,13 @@ This recipe is also demonstrated in a YouTube flyover at https://youtu.be/ksYXtN
2. Click "Next"

2. *Set the project options*
1. Set Product Name to "iOS Example"
1. Set Product Name to "Example"
2. Set Team to "None"
3. Set Organization Identifier to `com.AN.ORGANIZATION.IDENTIFIER`
4. Set User Interface to "SwiftUI"
5. Set Language to "Swift"
7. Ensure “Use Core Data” and "Include Tests" are not selected
6. Set Storage to "None"
7. Ensure "Include Tests" is not selected
8. Click “Next"
3. *Create the project*
1. Ensure “Create Git Repository on my Mac" is not selected
Expand All @@ -82,46 +86,36 @@ This recipe is also demonstrated in a YouTube flyover at https://youtu.be/ksYXtN

### IV. Use the directory layout structure like Alamofire

1. *Move iOS Example source code to a folder named "Sources"*
1. Open the file iOS Example.xcodeproj in Xcode
1. *Move Example source code to a folder named "Sources"*
1. Open the file Example.xcodeproj in Xcode
2. Show the Project navigator on the left (folder icon)
3. Use the Project navigator to select the "iOS Example" folder (gray icon)
3. Use the Project navigator to select the "Example" folder (gray icon)
4. From the Project navigator, rename this folder as "Sources"
* :information_source: The Alamofire project uses [the folder name "Source"](https://github.com/Alamofire/Alamofire/tree/master/Example/Source) but we choose "Sources" here to be consistent with [the default of Swift Package Manager](https://github.com/apple/swift-package-manager/blob/4fd4df4275627ebc91a0f288c38658738cd9fa0f/Sources/Workspace/InitPackage.swift#L275)
* :information_source: The Alamofire project uses [the folder name "Source"](https://github.com/Alamofire/Alamofire/tree/master/Example/Source) but we choose "Sources" here to be consistent with [the default of Swift Package Manager](https://github.com/apple/swift-package-manager/blob/swift-5.9.2-RELEASE/Sources/Workspace/InitPackage.swift#L505)
2. *Fix the Info.plist file configuration and preview content folder (Xcode makes renaming folders a pain)*
1. Click "iOS Example" on the left (the blue icon)
2. Click the target "iOS Example" in the middle (white app icon)
1. Click "Example" on the left (the blue icon)
2. Click the target "Example" in the middle (gray app icon)
3. Click "Build Settings" on the top of the middle
6. Enter "Development Assets" in the search box
7. In the "Deployment" section, edit the value from “iOS Example/Preview Content” to "Sources/Preview Content"
7. In the "Deployment" section, edit the value from “Example/Preview Content” to "Sources/Preview Content"

### V. Add some functionality to your iOS Example application
### V. Add some functionality to your Example application

1. Use Terminal.app to insert some files into the project

```sh
cd ~/Desktop/xxPROJECTxNAMExx/iOS\ Example/Sources
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/master/xxPROJECTxNAMExx/iOS%20Example/Sources/ContentView.swift' -o ContentView.swift
cd ~/Desktop/xxPROJECTxNAMExx/Example/Sources
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/main/xxPROJECTxNAMExx/Example/Sources/ContentView.swift' -o ContentView.swift
```

### VI. Make your iOS Example application depend on your module
### VI. Make your Example application depend on your module

1. Open iOS Example.xcodeproj in Xcode
2. In Xcode, choose File > Add Packages...
1. Open Example.xcodeproj in Xcode
2. In Xcode, choose File > Add Package Dependencies...
1. Click "Add Local..."
2. Select the `xxPROJECTxNAMExx` folder on your desktop
3. Click "Add Package"

3. *Add a build dependency*
1. :information_source: You may or may not need to quit and reopen Xcode to proceed and see the required library, this is a known Xcode issue
1. Click "iOS Example" on the left (the blue icon)
1. Click the target "iOS Example" in the middle (white app icon)
1. Click "Build Phases" on the top
1. Open the section Link Binary With Libraries
1. Click the plus (+) button
1. Select `xxPROJECTxNAMExx` (the building icon)
1. Click "Add"

### VII. Add additional project management files to the module

*These files represent best practices which every Swift module author should adopt for published code.*
Expand All @@ -130,35 +124,33 @@ This recipe is also demonstrated in a YouTube flyover at https://youtu.be/ksYXtN

```sh
cd ~/Desktop/xxPROJECTxNAMExx/
curl 'https://raw.githubusercontent.com/github/gitignore/master/Swift.gitignore' -o .gitignore
curl 'https://raw.githubusercontent.com/github/gitignore/main/Swift.gitignore' -o .gitignore
mkdir -p .github/workflows
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/master/xxPROJECTxNAMExx/.github/workflows/ci.yml' -o .github/workflows/ci.yml
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/master/xxPROJECTxNAMExx/LICENSE' -o LICENSE
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/master/xxPROJECTxNAMExx/README.md' -o README.md
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/master/xxPROJECTxNAMExx/CHANGELOG.md' -o CHANGELOG.md
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/master/xxPROJECTxNAMExx/CONTRIBUTING.md' -o CONTRIBUTING.md
echo 'xxPROJECTxNAMExx.framework.zip' >> .gitignore
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/master/xxPROJECTxNAMExx/Tests/CheckCocoaPodsQualityIndexes.rb' -o Tests/CheckCocoaPodsQualityIndexes.rb
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/main/xxPROJECTxNAMExx/.github/workflows/ci.yml' -o .github/workflows/ci.yml
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/main/xxPROJECTxNAMExx/LICENSE' -o LICENSE
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/main/xxPROJECTxNAMExx/README.md' -o README.md
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/main/xxPROJECTxNAMExx/CHANGELOG.md' -o CHANGELOG.md
curl 'https://raw.githubusercontent.com/fulldecent/swift5-module-template/main/xxPROJECTxNAMExx/CONTRIBUTING.md' -o CONTRIBUTING.md
```
### VIII. Remove identifying parts of your project

*This step allows everybody to achieve byte-for-byte consistency with [the published Swift 5 Module Template](https://github.com/fulldecent/swift5-module-template/tree/master/xxPROJECTxNAMExx) but otherwise provides no value to you.*
*This step allows everybody to achieve byte-for-byte consistency with [the published Swift 5 Module Template](https://github.com/fulldecent/swift5-module-template/tree/main/xxPROJECTxNAMExx) but otherwise provides no value to you.*

1. Use Terminal.app to find and replace all occurrences of hard-coded strings with template variables

```sh
find -E ~/Desktop/xxPROJECTxNAMExx \
-regex '.*\.(h|swift)' -exec sed -i '' -E -e '
-type f -name '*.swift' -exec sed -i '' -E -e '
s-(// +Created by ).*( on ).*\.-\1__AUTHOR NAME__\2__TODAYS_DATE__.-
s-(// +Copyright © ).*-\1__TODAYS_YEAR__ __ORGANIZATION NAME__. All rights reserved.-' \
'{}' \;
```

## Taste testing

1. Open iOS Example.xcworkspace in Xcode
1. Open Example.xcodeproj in Xcode

2. Use the scheme navigator to select iOS Example and the latest iPhone version
2. Use the scheme navigator to select Example and the latest iPhone version simulator

3. Choose Product > Run

Expand Down
File renamed without changes.

0 comments on commit c47eb05

Please sign in to comment.