diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9b187190..e252ce81 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,5 +1,5 @@ # @suho is the Team Lead and the others are team member -* @suho @blyscuit @edgarss @markgravity @minhnimble @nmint8m @phongvhd93 @vnntsu +* @suho @blyscuit @edgarss @markgravity @minhnimble @nmint8m @phongvhd93 @vnntsu @ducbm051291 @Shayokh144 # Engineering Leads CODEOWNERS @nimblehq/engineering-leads diff --git a/.github/wiki/Automating-Wiki.md b/.github/wiki/Automating-Wiki.md index 425d6c2f..1060486e 100644 --- a/.github/wiki/Automating-Wiki.md +++ b/.github/wiki/Automating-Wiki.md @@ -2,4 +2,4 @@ 1. Setup the Github Wiki by following this [official guide](https://docs.github.com/en/communities/documenting-your-project-with-wikis/adding-or-editing-wiki-pages#adding-wiki-pages). 2. Create [Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token.) with `repo` scope enabled - a bot account is recommended to generate that token. -3. Create a [Repository Secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) with the above token, the default name for this secret is `NIMBLE_DEV_TOKEN`. \ No newline at end of file +3. Create a [Repository Secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) with the above token, the default name for this secret is `NIMBLE_DEV_TOKEN`. diff --git a/.github/wiki/Bitrise.md b/.github/wiki/Bitrise.md new file mode 100644 index 00000000..fda498a6 --- /dev/null +++ b/.github/wiki/Bitrise.md @@ -0,0 +1,66 @@ +# Bitrise +Use the Bitrise template to start a new project with Bitrise as the CI/CD tool. + +## Workflows and Steps + +Out of the box, the Bitrise Template has the following workflows and steps: + +| test | deploy_app_store | deploy_staging | deploy_release_firebase | +|---------------------------|---------------------------------------------------------|-----------------------------------------|-------------------------------------------| +| Git Clone Repository | Git Clone Repository | Git Clone Repository | Git Clone Repository | +| Bitrise.io Cache:Pull | Bitrise.io Cache:Pull | Bitrise.io Cache:Pull | Bitrise.io Cache:Pull | +| Run CocoaPods install | Run CocoaPods install | Run CocoaPods install | Run CocoaPods install | +| Fastlane - Build and Test | Xcode Test for iOS | Xcode Test for iOS | Xcode Test for iOS | +| Fastlane - Run XCov | Fastlane Match | Fastlane Match | Fastlane Match | +| Danger | Fastlane - Build and Upload Production App to App Store | Fastlane - Build and Upload Staging App | Fastlane: Build and Upload Production App | + +## Trigger Map + +| Workflow | Trigger | +|-------------------------|-------------------------| +| test | Create or Update a PR | +| deploy_staging | Push branch `develop` | +| deploy_release_firebase | Push branch `release/*` | +| deploy_app_store | Push branch `master` | + +## Environment and Secrets +### App Environtment Variables +- BITRISE_PROJECT_PATH +> e.g., ExampleApp.xcodeproj or in case you're using CocoaPod, it is ExampleApp.xcworkspace. + +- TEAM_ID +> This is your Apple Team ID (e.g., T3T4E84BAA), you can find it in `Membership` at Apple developer portal. + +- MATCH_REPO_URL +> Link to a repository that contains your Fastlane Match it can be either HTTPS or SSH link (e.g., https://github.com/nimblehq/fastlane-match.git) + +### Workflow Environment Variables +All four workflows have their own variables: + +- BUNDLE_ID +> e.g., com.nimblehq.exampleApp + +*Depending on which workflow, the value of those variables may differ from other workflows.* + +### Secrets + +- MATCH_PASSWORD +> This is an encryption password for the Match Repo + +## Installation +1. Follow the setup instruction in [`README.md`](https://github.com/nimblehq/ios-templates#readme). +2. To connect your repository to Bitrise please follow the instruction in this page: [Adding a new app](https://devcenter.bitrise.io/en/getting-started/adding-your-first-app.html). +3. Make sure the option where the `bitrise.yml` locate is set to `Store in-app repository`. +

+ Bitrise Store in-app repository +

+ +4. Provide all the required variables and secrets. +> Final project directory structure +``` +ROOT +├── ExampleApp.xcworkspace +├── bitrise.yml +├──... +``` +5. Push changes to SCM. diff --git a/.github/wiki/Getting-Started.md b/.github/wiki/Getting-Started.md new file mode 100644 index 00000000..0d2af9ad --- /dev/null +++ b/.github/wiki/Getting-Started.md @@ -0,0 +1,13 @@ +## Requirements + +- Xcode `13.3+` +- Ruby `3.1.2` + +## Use the template + +1. Create your repository by pressing the `Use this template` button in this repository or create a new repository and use `nimblehq/ios-templates` as a repository template. +2. Clone your repository +3. Setup the project by running the following command in your terminal: + ```bash + sh make.sh --bundle-id [BUNDLE_ID_PRODUCTION] --bundle-id-staging [BUNDLE_ID_STAGING] --project-name [PROJECT_NAME] + ``` diff --git a/.github/wiki/Github-Actions.md b/.github/wiki/Github-Actions.md new file mode 100644 index 00000000..69a08361 --- /dev/null +++ b/.github/wiki/Github-Actions.md @@ -0,0 +1,65 @@ +# Github Actions + +Use the GitHub Actions template to start a new project with GitHub Actions as the CI/CD tool. + +Out of the box, the template contains the following workflows: + +## Workflows + +There are currently 4 workflows: + +- test +- deploy_firebase +- deploy_release_firebase +- deploy_app_store + +|Task/Workflow |test |deploy_firebase|deploy_release_firebase|deploy_app_store| +|------------------------|------------------------------------------------------------------------------------------------------------------------------------|---------------|-----------------------|----------------| +|Trigger |merge or push to feature/chore/bug branch |merge or push to develop branch|merge or push to release branch|merge or push to main/ master branch| +|Lint (async) |✅ |✅ |✅ |✅ | +|Test |✅ |✅ |✅ |✅ | +|Deploy |❌ |Staging build to Firebase|Production build to Firebase|Production build to App Store| + +## Jobs + +### Lint + +1. Check out the current version. +2. Run a SwiftLint on a Linux machine. Show result on pull request's check. + +### Test + +1. Check out the current version. +2. Install dependencies including Gem, Fastlane, and Cocoapods. +3. Run Test on staging scheme and show result on pull request's check. + +### Deploy + +1. Proceed to 4 if this job is running after `Test` job +2. Check out the current version. +3. Install dependencies including Gem, Fastlane, and Cocoapods. +4. Install provisioning profiles and certificates using Fastlane match. +5. Build archive version of the specified scheme. +6. Deploy to Firebase Distribution, TestFlight, or App Store. + +# Installation + +## Environment Secrets + +Make sure the following secrets are set up. + +|Secret |Description |test|deploy_firebase|deploy_release_firebase|deploy_app_store | +|------------------------|------------------------------------------------------------------------------------------------------------------------------------|----|---------------|-----------------------|-----------------------------------| +|SSH_PRIVATE_KEY |SSH key connected to a user with access to the match repo for check out the match repo. |- |✅ |✅ |✅ | +|MATCH_PASS |Fastlane Match Passphrase for decrypting a match repository. |- |✅ |✅ |✅ | +|APPSTORE_CONNECT_API_KEY|App Store Connect API https://docs.fastlane.tools/actions/app_store_connect_api_key/ for uploading build to TestFlight or App Store.|- |- |- |✅ | +|FIREBASE_TOKEN |Firebase token https://firebase.google.com/docs/cli#cli-ci-systems for uploading build to Firebase Distributions and Analytics. |- |✅ |✅ |✅ For uploading dSYM to Crashlytics| + +## Installation + +1. Following the setup instruction in `README.md`. +2. Modify the files with project's values: + - fastlane/Matchfile + - fastlane/Constants/Constants.rb +3. Provide SECRETS noted in `yml` file in [Github Project's Setting](https://docs.github.com/en/actions/reference/encrypted-secrets) +4. Push changes to Github \ No newline at end of file diff --git a/.github/wiki/Home.md b/.github/wiki/Home.md index de8a50eb..3158e255 100644 --- a/.github/wiki/Home.md +++ b/.github/wiki/Home.md @@ -2,4 +2,4 @@ This wiki contains documentation about our optimized iOS template. -If you want to understand our templates, let's jump into [[Getting Started]]. +If you want to start with our templates, let's jump into [[Getting Started]]. diff --git a/.github/wiki/Project-Configurations.md b/.github/wiki/Project-Configurations.md new file mode 100644 index 00000000..2fefdf34 --- /dev/null +++ b/.github/wiki/Project-Configurations.md @@ -0,0 +1,136 @@ +## Project Configurations + +This document presents in detail the set of configurations used in the iOS projects developed at Nimble. Included in this document are: + +- Terminologies and topics related to project configurations. +- Basic targets, schemes, build settings options, etc., for building a project. + +### Targets + +A target specifies a product to build, such as an iOS, watchOS, or macOS app. + +When creating a project from a template, a default target will be added automatically for the main application. + +There are 3 default targets in a project: + +- {ProjectName} +- {ProjectName}Tests +- {ProjectName}UITests + +### Schemes + +A scheme is a collection of settings that specifies the targets to build for a project, the build configuration to use, and the executable environment to use when the product is launched. + +The 2 main schemes in a project: + +- {ProjectName} +- {ProjectName} Staging + +### Build Configurations in Schemes + +It is possible to build a scheme with different Build Configurations. Initially, there are 2 basic configurations for a project generated automatically by Xcode, which are: + +- Debug +- Release + +However, these basic configurations are not enough for our development process. Since our team always wants to ensure the application is working in a designated manner, additional levels of testing are required before the application is ready to be used. + +The recommended set of configurations to have is: + +- Debug Staging +- Release Staging +- Debug Production +- Release Production + +### Active Compilation Conditions + +Having distinct flags for each configuration is the preferred solution. + +Xcode provides a build setting named `Active Compilation Conditions`, which supports passing conditional compilation flags to the Swift compiler. + +In our iOS template project, there are three custom conditional compilation flags: `DEBUG`, `STAGING`, `PRODUCTION`. The following table will describe how the developers differentiate a configuration from the others. + +| Build Configurations | DEBUG | STAGING | PRODUCTION | +|---|---|---|---| +| Debug Staging | ✔︎ | ✔︎ | | +| Release Staging | | ✔︎ | | +| Debug Production | ✔︎ | | ✔︎ | +| Release Production | | | ✔︎ | + +The major advantage of custom flags is to allow customizable specific features based on a particular environment. + +Example: + +Specify a value based on the environment: + +```swift +enum Environment { + + static func based(staging: T, production: T) -> T { + #if PRODUCTION + return production + #else + return staging + #endif + } +} +``` + +During the development process, all functionalities and frameworks are available in the application. However, there can be situations when the developers just want to turn on some features for a particular environment without creating separate modules for the application. In these cases, declaring a condition to include or exclude code using `Active Compilation Conditions` is the recommended solution. + +```swift +#if DEBUG + // Code the app includes in DEBUG environments +#else + // Code the app includes when it is not build with DEBUG environments +#endif +``` + +### Xcode Configuration File + +A Configuration Settings File (`*.xcconfig`), also known as a build configuration file, is a plain text file that defines and overrides the default build settings for a particular build configuration of a project or target. This type of file can be edited outside of Xcode and integrates well with source control systems. + +Because of different settings for each environment (such as bundle identifiers, endpoints, etc.), the developers also define them in different *.xcconfig files. + +### Settings Bundle + +To support multiple levels of testing, the `Settings Bundle` is usually integrated along with the dev configurations (a **.plist** file). In addition, the Settings Bundle facilitates the testing process. It creates a shortcut to change environment values without using any third-party API or server. + +Settings Bundle works well when developing: + +- [Feature toggle](https://martinfowler.com/articles/feature-toggles.html) +- [A/B Testing](https://en.wikipedia.org/wiki/A/B_testing) +- Change API endpoints for testing the application with multiple servers +- Define a list of prefilled credentials and a toggle for prefilling + +The Settings Bundle is only enabled on Dev environments. It is optional for Beta environments. + +### Debug Symbol File + +Basically, the debug Symbol file (`dSYM` file) is used to de-obfuscate stack traces from crashes happening on the production app. The dSYM files store the debug symbols for the application. Then services (like Crashlytics) use the dSYM files to replace the symbols in the crash reports with the originating locations in the source code. Hence, the crash reports will be more readable and understandable. + +Go to **Build Settings** → **Debug Information Format**. The debug symbols with a dSYM file (DWARF with dSYM file) are enabled for the release build by default. + +A benefit of using the dSYM is reducing the binary size when building an application. Read more about it in the technical note [TN2151](https://developer.apple.com/library/archive/technotes/tn2151/_index.html). + +Only include the dSYM file for release builds. + +| Build Configurations | Included dSYM file | +|---|---| +| Debug Staging | | +| Release Staging | ✔︎ | +| Debug Production | | +| Release Production | ✔︎ | + +### Enable Bitcode + +Bitcode is a technology that enables recompiling applications to reduce their size. The recompilation happens when the application is uploaded to the App Store Connect or exported for Ad Hoc, Development, or Enterprise distribution. + +Enable build with bitcode for Production only. + +| Build configurations | Enable Bitcode | +|---|---| +| Debug Staging | | +| Release Staging | | +| Debug Production | | +| Release Production | ✔︎ | diff --git a/.github/wiki/Project-Dependencies.md b/.github/wiki/Project-Dependencies.md new file mode 100644 index 00000000..bcf3f398 --- /dev/null +++ b/.github/wiki/Project-Dependencies.md @@ -0,0 +1,62 @@ +To simplify setup for developers new to the application, as well as having a reliable build system that is also able to run in a reproducible fashion. The creation and set up of a new project will be faster and safer. It will require only the language runtime (`Ruby`) and dependency manager installed as prerequisites. + +The project normally contains: + +- Fastlane: is the easiest way to automate beta deployments and releases for the `iOS` (also `Android`) applications. 🚀 It handles all tedious tasks, such as generating screenshots, dealing with code signing, and releasing the application. +- Cocoapods: manages dependencies for Xcode projects. Cocoapods aims to improve the engagement with, and discoverability of, third-party open-source Cocoa libraries. Developers only need to specify the dependencies in a file named `Podfile`. Cocoapods recursively resolves dependencies between libraries, fetches source code for all dependencies, and creates and maintains an Xcode workspace to build the project. +- Swift Package Manager: a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies. + +## Dependencies + +### Bundler + +[Bundler](https://bundler.io/) is a Ruby package manager, think of it as a Cocoapods for ruby plugins that will be used for the project. Keeping package versions the same on all development machines and Continuous Development machines reduces unnoticed bugs from occurring. Noteworthy packages include `Fastlane`, `Firebase-cli`, and `Cocoapods`. + +### Cocoapods + +[Cocoapods](https://cocoapods.org/) manages iOS packages to keep consistency throughout development machines. + +### Fastlane + +[Fastlane](https://fastlane.tools/) automates test, build, and most importantly: certificates and profiles which are a core part of the App Store ecosystem. + +### Firebase + +The main usage of [Firebase](https://firebase.google.com/) for our team is `Firebase Crashlytics` and `Firebase Distribution`. `Firebase Crashlytics` is used to track, prioritize, and fix stability issues that erode the app quality. `Firebase Distribution` is the primary method for QA and Client to download applications for testing and presenting purposes. In some projects, `Firebase Analytics` is being used to track and analyze users' behavior for marketing purposes. + +## Libraries + +### Alamofire + +[Alamofire](https://github.com/Alamofire/Alamofire) is a networking library for Swift projects. Alamofire is used as a base for our Networking layer to streamline API calls in all projects, allowing developers to switch between projects without an issue. + +### SnapKit (pre-SwiftUI) + +[SnapKit](https://github.com/SnapKit/SnapKit) is the tool for layout user interface with ease and easier to establish a team's convention. SnapKit applies Auto Layout using a more concise syntax. This allows the UI to be responsive on different devices. + +### RxSwift + +[RxSwift](https://github.com/ReactiveX/RxSwift) is the library for writing Swift in the reactive programming way. RxSwift added a reactive framework for Swift with syntax closely resembling other Rx frameworks. Although it is possible to implement reactive programming for Swift, RxSwift can bypass problems that arise from maintaining large plugins and allow developers from other platforms to easily understand RxSwift syntax. + +### IQKeyboardManagerSwift + +[IQKeyboardManager](https://github.com/hackiftekhar/IQKeyboardManager) is a plugin for `UIScrollView`. IQKeyboardManager will detect when the keyboard is showing and adjust the view so that the view is not blocked by the keyboard. IQKeyboardManager is the go-to solution because of the ease of installation and history of maintenance by the developers. + +### SwiftLint + +[SwiftLin](https://github.com/realm/SwiftLint) is used to enforce our team's code convention. SwiftLint is the perfect tool for this task as it is customizable, lightweight, and automate-able. Our team installs SwiftLint with `Ruby` to allow Continuous Integration machine capability to replicate local lint. SwiftLint is integrated with Xcode to display a warning and halt build when error. + +### KeychainAccess + +[KeychainAccess](https://github.com/kishikawakatsumi/KeychainAccess) is a wrapper for Keychain, making storing data with Apple's encryption as convenient as using `UserDefault`. + +### Sourcery + +Swift code generator running on top of Stencil. [Sourcery](https://github.com/krzysztofzablocki/Sourcery) is used to generate Protocol's Mock for Unit Testing purposes. We include Sourcery in `podfile` and add a shell script to Xcode Build Phrase `./Pods/Sourcery/bin/sourcery`. + +### SwiftFormat + +[SwiftFormat](https://github.com/nicklockwood/SwiftFormat) is a code formatter for Swift language. The template uses SwiftFormat as a code convention enforcer. When SwiftFormat runs, the source code is reformatted according to the applied rules. This helps with keeping code conventions and reducing the number of warnings. + +> When the `SwiftFormat` runs, the code is reformatted, making them lose the ability to undo and redo. This could cause inconvenience to the development, so the current version of the template runs a `SwiftFormat` command only when starting a `Test` build. + diff --git a/.github/wiki/Standard-File-Organization.md b/.github/wiki/Standard-File-Organization.md index 23eec7f7..885f3f11 100644 --- a/.github/wiki/Standard-File-Organization.md +++ b/.github/wiki/Standard-File-Organization.md @@ -126,7 +126,7 @@ To keep all current and upcoming iOS projects aligned, we standardize an iOS pro    └── TestError.swift ``` -## **README.md** +## README.md `README.md` introduces the overview of the project, for example: diff --git a/.github/wiki/_Sidebar.md b/.github/wiki/_Sidebar.md index c8ecb79f..ee30afcf 100644 --- a/.github/wiki/_Sidebar.md +++ b/.github/wiki/_Sidebar.md @@ -1,5 +1,11 @@ * [[Home]] +* [[Getting Started]] +* [[Automating Wiki]] **Technical document** * [[Standard File Organization]] +* [[Project Configurations]] +* [[Project Dependencies]] +* [[Github Actions]] * [[Self Hosted Github Actions]] +* [[Bitrise]] diff --git a/.github/wiki/assets/images/bitrise/Bitrise-YML-Storage-Location.png b/.github/wiki/assets/images/bitrise/Bitrise-YML-Storage-Location.png new file mode 100644 index 00000000..a8791cbb Binary files /dev/null and b/.github/wiki/assets/images/bitrise/Bitrise-YML-Storage-Location.png differ diff --git a/.swiftformat b/.swiftformat index 0ddedad7..bfd8bcc5 100644 --- a/.swiftformat +++ b/.swiftformat @@ -10,3 +10,4 @@ --disable wrapSwitchCases --disable blankLinesAtStartOfScope --stripunusedargs closure-only +--extensionacl on-declarations diff --git a/.tuist-version b/.tuist-version index e7034819..a4f52a5d 100644 --- a/.tuist-version +++ b/.tuist-version @@ -1 +1 @@ -2.3.2 \ No newline at end of file +3.2.0 \ No newline at end of file diff --git a/Podfile b/Podfile index 62a3b5db..22466897 100644 --- a/Podfile +++ b/Podfile @@ -7,7 +7,9 @@ def testing_pods pod 'Nimble' pod 'RxNimble', subspecs: ['RxBlocking', 'RxTest'] pod 'RxSwift' - pod 'Sourcery' + # TODO: Remove or update the version of `1.8.0` to the newest version (not 1.8.1) when init a new project. + # Currently, there is a bug on `1.8.1` - the newest version. + pod 'Sourcery', '1.8.0' pod 'SwiftFormat/CLI' end diff --git a/Project.swift b/Project.swift index 4505da3a..58c34319 100644 --- a/Project.swift +++ b/Project.swift @@ -9,6 +9,10 @@ extension Project { return Project( name: name, organizationName: "Nimble", + options: .options( + disableBundleAccessors: true, + disableSynthesizedResourceAccessors: true + ), settings: .settings( configurations: BuildConfiguration.allCases.map { $0.createConfiguration(projectName: name) } ), diff --git a/README.md b/README.md index e7a04757..e420cd35 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,50 @@ -# ios-template +

+ Nimble logo +

+ +

+ iOS Templates +

+ +--- Our optimized iOS template used in our projects using Xcode Templates -## Requirements +## Getting Started -Xcode 12.0 +### Requirements -## Wiki +- Ruby `3.1.2` +- Xcode `13.3+` -1. [Standard File Organization](https://github.com/nimblehq/ios-templates/wiki/Standard-file-organization) -2. [Project Configurations](https://github.com/nimblehq/ios-templates/wiki/Project-configurations) -3. [Why having project's dependencies](https://github.com/nimblehq/ios-templates/wiki/Why-having-project%27s-dependencies) -4. [Github Actions](https://github.com/nimblehq/ios-templates/wiki/Github-Actions-Templates) -5. [Bitrise Template](https://github.com/nimblehq/ios-templates/wiki/Bitrise-Template) +### Use the template +1. Create your repository by pressing the `Use this template` button in this repository or create a new repository and use `nimblehq/ios-templates` as a repository template. +2. Clone your repository +3. Setup the project by running the following command in your terminal: + ```bash + sh make.sh --bundle-id [BUNDLE_ID_PRODUCTION] --bundle-id-staging [BUNDLE_ID_STAGING] --project-name [PROJECT_NAME] + ``` -# Tuist Installation and Documentations +## Full Documentation +See the [Wiki](https://github.com/nimblehq/ios-templates/wiki/) for full documentation, project details and other information. -Run the following command in your terminal for the Tuist installation: +## License +This project is Copyright (c) 2014 and onwards. It is free software, +and may be redistributed under the terms specified in the [LICENSE] file. -```bash -bash <(curl -Ls https://install.tuist.io) -``` +[LICENSE]: /LICENSE -Documentation : [Tuist Official Documents](https://docs.tuist.io/tutorial/get-started) +## About +![Nimble](https://assets.nimblehq.co/logo/dark/logo-dark-text-160.png) -## How to use +This project is maintained and funded by Nimble. -### Install Script +We love open source and do our part in sharing our work with the community! +See [our other projects][community] or [hire our team][hire] to help build your product. -Execute the following command -``` -sh make.sh --bundle-id [BUNDLE_ID_PRODUCTION] --bundle-id-staging [BUNDLE_ID_STAGING] --project-name [PROJECT_NAME] -``` +[community]: https://github.com/nimblehq +[hire]: https://nimblehq.co/ \ No newline at end of file diff --git a/Tuist/Config.swift b/Tuist/Config.swift deleted file mode 100644 index e39707e0..00000000 --- a/Tuist/Config.swift +++ /dev/null @@ -1,9 +0,0 @@ -import ProjectDescription - -let config = Config( - generationOptions: [ - .disableAutogeneratedSchemes, - .disableSynthesizedResourceAccessors, - .disableBundleAccessors - ] -) diff --git a/Workspace.swift b/Workspace.swift new file mode 100644 index 00000000..1ac6aca0 --- /dev/null +++ b/Workspace.swift @@ -0,0 +1,17 @@ +import ProjectDescription + +let workspace = Workspace.workspace(name: "{PROJECT_NAME}") + +extension Workspace { + + static func workspace(name: String) -> Workspace { + return Workspace( + name: name, + projects: ["./**"], + generationOptions: .options( + autogeneratedWorkspaceSchemes: + .disabled + ) + ) + } +} diff --git a/make.sh b/make.sh index e3a0c881..632b1294 100644 --- a/make.sh +++ b/make.sh @@ -80,7 +80,7 @@ if [ -z "$bundle_id_production" ] || [ -z "$bundle_id_staging" ] || [ -z "$proje fi # Enforce package name -regex='^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+[0-9a-z_]$' +regex='^[a-z][a-z0-9_]*(\.[a-z0-9_-]+)+[0-9a-z_-]$' if ! [[ $bundle_id_production =~ $regex ]]; then die "Invalid Package Name: $bundle_id_production (needs to follow standard pattern {com.example.package})" fi