Skip to content

Latest commit

 

History

History
259 lines (153 loc) · 14.8 KB

objectivec-swift-ios-osx.md

File metadata and controls

259 lines (153 loc) · 14.8 KB

logo

XYO Best Practices (ObjecticeC/Swift/iOS/OSX)

Editor/IDE (XCode)

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.

Features

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.

Languages (Swift)

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.

Compiler (XCode)

Xcode

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.

Linter (XCode)

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.

SwiftLint Rules

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

Testing iOS/MacOS

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.

Code Quality (CodeClimate/BetterCodeHub/Codeacy/SonarQube)

Dependency Checking

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.

Code Freshness (Checking dependency drift)

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.

3rd Party Libraries

See the above section on Dependency Tracking for guidelines.

Internal Libraries

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.

CI/CD (Github Actions)

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.

Publishing (Cocoapods)

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

Build Process

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

Platform/API Targeting

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.

Design Issues (Platform vs. XY)

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.

App Store Guidance

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.

Authentication

Firebase/Fabric Integration

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.

XY Account Integration

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.

Project Structure

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.

Apps

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.

Frameworks

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.

Runtime (Swift)

XYO Tools (sdk-base-swift)

Logging (Firebase)

Platforms

iOS

Native

Unity

Unreal

OSX

Native

Source Control (GitHub)

Git Branch Standards

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.

Naming Your Branches

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

Git Flow

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

Screenshot

Licensing

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.

Our Licenses

LGPL 3.0

Custom

3rd Party Licenses