Apple releases a new major version of Xcode with each new major version of iOS, along with a number of dot releases inbetween. The currently stable version, 10.2 provides support for Swift 5, which is compatible with Swift 4.2. Developers should download and experiment with beta versions of Xcode as they are released around WWDC in prepration to move to the new version in the fall.
With Swift 5 comes a level of language stability that has been missing prior. Developers should be encouraged to adopt new conventions and features in the language spec, either as part of a technical debt project or a new feature or application.
The current production targeted version of Swift is 4.2. Swift 5 will be released as part of Xcode 10.2, providing a few new language features as well as the promise of a significant decrease in the size of compiled code. Migration to Swift 5 should occur as part of a technical debt project in the near future, although Swift 5’s compiler will work with libraries and code developed for Swift 4.
Swift documentation is avaliable here.
Apple releases a new major version of Xcode with each new major version of iOS, along with a number of dot releases inbetween. The currently stable version, 10.2 provides support for Swift 5, which is compatible with Swift 4.2. Developers should download and experiment with beta versions of Xcode as they are released around WWDC in prepration to move to the new version in the fall.
Enforcement of basic coding standards will be provided by SwiftLint. In order to easily maintain the version, SwiftLint should be installed as a Cocoapod and not via a third-party installation manager such as homebrew
. SwiftLint will also integrate with both Fastlane and Danger.
disabled_rules: # rule identifiers to exclude from running
- identifier_name
- nesting
- function_parameter_count
- class_delegate_protocol
- todo
opt_in_rules: # some rules are only opt-in
- control_statement
- empty_count
- trailing_newline
- colon
- comma
included: # paths to include during linting. `--path` is ignored if present.
- Source
excluded: # paths to ignore during linting. Takes precedence over `included`.
- Carthage
- Pods
# configurable rules can be customized from this configuration file
# binary rules can set their severity level
force_cast: warning # implicitly. Give warning only for force casting
force_try:
severity: warning # explicitly. Give warning only for force try
type_body_length:
- 300 # warning
- 500 # error
function_body_length:
warning: 80
error: 120
# or they can set both explicitly
file_length:
warning: 500
error: 800
large_tuple: # warn user when using 3 values in tuple, give error if there are 4
- 3
- 4
line_length:
warning: 160
error: 200
# naming rules can set warnings/errors for min_length and max_length
# additionally they can set excluded names
type_name:
min_length: 3 # only warning
max_length: # warning and error
warning: 45
error: 50
excluded: iPhone # excluded via string
reporter: "xcode"
indentation: 3
Apple provides the XCTest framework for unit testing of application code. This framework is relatively straightforward.
The following tutorial on XCTest provides a basic overview.
Alternatively, a developer can choose to use Quick which provides a behavior-driven testing framework.
Any testing framework will be integrated into the Fastlane build process.
Projects typically have one or more dependency to either an internal or third-party framework. These should use a dependency framework such as CocoaPods or Carthage to ensure that team members can check out either master
or develop
and be guaranteed the projects will build and run without issue.
Internally, the commonly used dependency manager is CocoaPods, which uses a Podfile.lock
file to track the currently installed versions for the project. This file must always be checked into the project once it is generated by pod install
. In this way, it is not necessary to store the code from these frameworks in git, so the Pods
directory is excluded in every .gitignore
.
Once a new version of a framework is available, a branch should be created before running pod update
, which will pull the newest versions included in the Podfile
. A pull request can then be made to ensure all unit tests are run via CI before allowing the updated Podfile.lock
to be merged.
A codebase should strive to use the latest stable versions of compilers, features, and third-party libraries if applicable. Over time these aspects will be updated and improved upon, and the original code can age out and become incompatible with the tooling and libraries it may rely on.
See the above section on Dependency Tracking for guidelines.
New projects may require internal-only libraries to be updated for new features. These changes may impact existing applications of the library. Keep this in mind and ensure that, if needed, time is set aside to update any older codebase which relies on the library that is being updated. Proper tagging and use of GitFlow will guarantee older builds can be built even if their shared libraries change.
Github Actions provides an automated CI/CD service for iOS and macOS projects, with the ability to run unit and UI tests as part of the build. In order for this to be most effective, the master
and develop
branches for a GitHub repository should have branch protection rules, with and pushed code and pull requests automatically kicking off a Github Action which would utlize Fastlane for running tests, computing test coverage, and deploying the build to Test Flight if so desired.
To publish your code to Cocoapods for use, you would need to consult an admin to get permission to run a session prior to executing a Github Action for publishing. Please consult the swift-pod-release.md
file in the Github Actions Folder
For a build Github Action, in a case by case basis, we can either go with an xcodebuild
, or a Fastlane run build. Github actions will execute either scenario in the VM. For reference of what a Github Action build looks like, consult the swift-pod-build.md
in the Github Actions Folder
As of this writing, we are currently targeting a minimum iOS version of 13 and a minimum macOS version of 10.15. A list of supported iOS devices is located here.
XYO applications may features design elements which are to be shared across mobile platforms. There may be cases where certain elements have a native representation on the platform which does not have an equivalent on the other. A good example of this is the UITabBar in iOS, which shows a row of icons at the bottom of the screen, allowing users to select a different view controller when they are tapped on. This is not provided natively on Android.
There is no hard and fast rule here for how best to provide a unique and engaging yet familiar experience across both platforms. Developers should work with the UI/UX designers to educate them on what is possible on each platform, and what may need to be custom built from the “parts bin” each provides.
Applications deployed to the App Store must follow Semantic Versioning
Certificate and provisioning profile management are handled via Fastlane’s match
. This allows for one centralized certificate for development across all XYO applications. The certificates and associated provisioning profiles are stored in a GitHub repository, tool-certs-ios
. Developers need to install Fastlane and can then download the certificates, allowing internal project repositories that contain Xcode projects to avoid reseting the Team setting for the project.
Fastlane provides a lane to handle automatic creation of screenshots across multiple languages and devices. More investigation is needed to see if this is a feature we would like to use.
Firebase integration is currently for authentication purposes. In the XYO Network app, this integration is wrapped in the XYAuthentication
static class, and can be used to handle user creation from email and password, a Google account, and Facebook, as well as handling post-login bootstrap functionality. Eventually, this should migrate to the XyCore
framework library.
Fabric’s Crashlytics is our current crash analysis provider. By the end of 2019 Crashlytics will be deprecated in favor of Firebase. All applications should be setup to use both Crashlytics and Firebase.
Going forward, our apps will use Firebase Authentication for authentication and base user management. Firebase provides integration with popular federated identity providers like Google and Facebook, as well as typical email and password based authentication. Integration is straighforward and is described in the documentation, and in wrapped in the XYAuthentication
static class for re-use across projects.
The associated user id created through Firebase Authentication can be used across all properties and platforms, allowing a single-sign experience.
All projects must contain a README.md
file which describes how to either build or install the project. Any public-facing framework or app must also contain a LICENSE
file with the appropriate contents.
Creating a new Xcode project (typically as a Single View App) will generate a directory structure, .xcodeproj
and info.plist
entries which match the name of the project. The developer should start by renaming the source directory to Source
and the ProjectNameTests
and ProjectNameUITests
folders to Tests
and UITests
. This is accomplished via a simple renaming of the ProjectName
subdirectories that contain the AppDelegate.swift
and associated boilerplate along with the test directories, and then performing a search and replace in the .xcodeproj
and info.plist
files. A template project will be created with a simple shell script to automate this work.
Our current naming convention for git repositories is type-usecase-language
. Framework projects, which will be used by internal apps and potentially published for public consumption should not replicate this as the project name, which would result in unhelpful import
statements in app code. Instead, using the same method described in the Apps section, the project and associated .xcodeproj
should be renamed to XyoFrameworkDescriptionSdk
. An example would be XyoBleSdk
or XyoUISdk
. A template project will be created with a simple shell script to automate this work.
A framework should also contain a .podspec
file and a Cartfile
for use with the two popular dependency management frameworks.
A sample app can be included as well if appropriate, with the project files located under SampleiOS
or SampleMacOS
directories. Do not commit Team settings for sample projects; always leave this set to None in the Signing section of the build target.
Make sure that the branch you are on is current and checked out from the most updated remote state
A key while working in a project is to ensure that you have the latest code from the other branches. especially those that you have checked out from.
Remember to frequently:
git fetch --all
git pull <remote name - ususally origin> <branch name>
We would recommend that you do this before pushing your committed code.
NOTE Related: make sure that you are in communication with your project team, and that you check GitHub for updates to the codebase, especially the branch that you are checked out from.
When you are checkout out new branches and naming them, you should follow a solid git flow method as outlined below:
- For feature branches
feature/<feature you are working on>
- For bug fix branches - hot
hotfix/<hotfix you are working on>
- For bug fix branches
fix/<fix you are working on>
NOTE Only if this bug-fix will not interfere with dev worklflow - For release branch
release/<version number>
NOTE Only if your project is working off of a release before merge into master
NOTE: Only the Develop and Release Branch can be merged into Master
In order to ensure that production-ready software is truly ready, we need to maintain a strong git flow. This means that we should only merge our develop or release branch into master - essentially we want to lock the master
, release
and develop
branches. The develop
branch should be the home for all tested and production ready code that is ready for a final review with included checks before being brought into master, we can also use release
for production staging. All checks would include CI/CD and code quality.
For feature branches, you should git checkout -b feature/<what feature name you are working on>
NOTE Feature branches should always and only be checked out from the latest develop branch.
Bug fixes, documentation updates, and minor styling should be done through a release
branch which would be checked out from the latest develop
branch after all feature branches have been merged into the develop
branch.
The develop
branch should also be where we conduct full app testing, as opposed to feature specific. To test features, you should make sure that all feature specifc tests pass in the feature
branch that you are working on.
If you feel you may need to do a hot-fix
directly to master, please communicate when to do this. Do Not Take Hot Fixes Lightly
Here is a diagram of good git flow
It is important to ensure that any licensing requirements are satisfied if using a third-party library that provides them. If you are unsure, consult with legal.