Skip to content

Commit

Permalink
Update project documentation (#813)
Browse files Browse the repository at this point in the history
  • Loading branch information
mathebox authored Sep 18, 2020
1 parent 32f8d4b commit 3e0ba85
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 61 deletions.
119 changes: 76 additions & 43 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,106 @@
# Contributing to _xikolo-ios_
# How to Contribute

### I want to report a problem or ask a question
Before submitting a new GitHub issue, please make sure to check the [existing GitHub issues](https://github.com/openHPI/xikolo-ios/issues). If this doesn't help, please [submit an issue](https://github.com/openHPI/xikolo-ios/issues/new/choose) on GitHub and provide detailed information.

### I want to contribute
Check out the [good first issues](https://github.com/openHPI/xikolo-ios/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) or any other unsassigned issue and submit a pull request when you are ready.
Check out the [good first issues](https://github.com/openHPI/xikolo-ios/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) or any other unassigned issue and submit a pull request when you are ready.

# Programming guidelines
## Programming Guidelines

### Fastlane
We use [fastlane](https://github.com/fastlane/fastlane) for repetitive tasks. Have a look at the [fastlane README](fastlane/README.md).

### Code formatting
#### Useful Commands When Developing
These custom commands ease the development process.

- `bundle exec fastlane lint`: Report linting warnings for the project (via swiftlint)
- `bundle exec fastlane format`: Resolve linting warning for the project -- not applicable to all warnings (via swiftlint)
- `bundle exec fastlane localize`: Extract keys for localized strings and add them to the respective `.strings` files (via BartyCrouch)
- `bundle exec fastlane check_core_data`: Check if the core data model was modified since the last tagged release
- `bundle exec fastlane increment_version_(patch|minor|major)`: Increase the app version project-wide in all modules
- `bundle exec fastlane changelog`: List all commits since the last tagged release
- `bundle exec fastlane export_localizations`: Export localizations and strip unwanted strings, that are excluded by BartyCrouch

### Code Formatting
In order to have a consistent code formatting, we would like you to set some settings:
- for less unneccessary whitespace changes please set both checkboxes in Xcode->Preferences->Text Editing regarding whitespaces
- use Unix-style line endings (LF)
- For fewer unneccessary whitespace changes, please select the following options in `Xcode > Preferences > Text Editing > Editing` (as of Xcode 12)
- Check box for `Automatically trim trailing whitespace`
- Check box for `Including whitespace-only lines`
- Choose `Unicode (UTF-8)` for `Default Text Encoding`
- Choose `macOS / Unix (LF)` for `Default Line Endings`

### R.swift
We use [R.swift](https://github.com/mac-cain13/R.swift) to keep a certain level of code quality. The linter will run for every pull request and there is also a fastlane command for this.
We use [R.swift](https://github.com/mac-cain13/R.swift) to avoid static strings in the codebase.

#### Using self
### Using self
One thing we can't enforce with R.swift is not to omit `self`. We prefer writing `self` explicitly because we believe this helps to distinguish between member attributes and local variabels.

For example:

```swift
class ChannelCell: UICollectionViewCell {

@IBOutlet private weak var shadowView: UIView!
@IBOutlet private weak var channelImage: UIImageView!

// ...

override func awakeFromNib() {
super.awakeFromNib()

self.shadowView.layer.roundCorners(for: .default, masksToBounds: false)
self.channelImage.layer.roundCorners(for: .default)
self.channelImage.backgroundColor = Brand.default.colors.secondary

self.shadowView.addDefaultPointerInteraction()
}

// ...
}
```

instead of

```swift
class ChannelCell: UICollectionViewCell {

@IBOutlet private weak var shadowView: UIView!
@IBOutlet private weak var channelImage: UIImageView!

// ...

override func awakeFromNib() {
super.awakeFromNib()

shadowView.layer.roundCorners(for: .default, masksToBounds: false)
channelImage.layer.roundCorners(for: .default)
channelImage.backgroundColor = Brand.default.colors.secondary

shadowView.addDefaultPointerInteraction()
}

// ...
}
```

### Localization
We use [BartyCrouch](https://github.com/Flinesoft/BartyCrouch) to ensure a complete localization of the applications. Simple run `bundle exec fastlane localize` to add entries for missing localizations in storyboard files and `NSLocalizedString` usages. Here are some tips to promote a consistent usage:

#### Exlusion of storyboard elements
#### Exlusion of Storyboard Elements
Add `#bc-ignore!` to 'Comment For Localizer' box in the utilities pane instead of adding `#bc-ignore!` to the elements value.
<div>
<img src="https://raw.githubusercontent.com/Flinesoft/BartyCrouch/stable/Images/IB-Comment-Exclusion-Example1.png" width="255px" height="437px">
<img src="https://raw.githubusercontent.com/Flinesoft/BartyCrouch/stable/Images/IB-Comment-Exclusion-Example2.png" width="254px" height="140px">
<img src="https://github.com/Flinesoft/BartyCrouch/blob/main/Images/IB-Comment-Exclusion-Example1.png" width="255px" height="437px">
<img src="https://github.com/Flinesoft/BartyCrouch/blob/main/Images/IB-Comment-Exclusion-Example2.png" width="254px" height="140px">
</div>

#### Support of stringsdict files
#### Support of stringsdict Files
Add `#bc-ignore!` to the user comment of `NSLocalizedString`
```
```swift
let format = NSLocalizedString("%d hours", comment: "<number> of hours #bc-ignore!")
```

#### Use name-spaced keys for NSLocalizedString
#### Use Name-Spaced Keys for NSLocalizedString
To add more context to single localized strings, we use name-spaced keys instead of the english text. The english text is stored in `Localizable.strings (Base)`. In this way we also avoid unneccesary long localization keys. So, we write:
```swift
NSLocalizedString("course.section-title.my courses", comment: ...)
Expand All @@ -47,32 +109,3 @@ instead of
```swift
NSLocalizedString("My Courses", comment: ...)
```

# How to publish a new version fo the apps
You have to be part of out core dev team to do this.

### Prerequirements:
- Configure fastlane
- make your own Appfile via `cp fastlane/Appfile.dummy fastlane/Appfile`
- set the following values
- `apple_id`
- `itunes_connect_id`
- for all available fastlane commands have a look at the [fastlane Readme](https://github.com/openHPI/xikolo-ios/tree/dev/fastlane/)
- Unlock the configuration files
- Install git-crypt via `brew install git-crypt`
- Retrieve the `xikolo-ios.key` from the openHPI team and run `git-crypt unlock /path/to/xikolo-ios.key`

### Release the apps
There is a fastlane command for each step. One for all flavor and one for each flavor (suffix: `_flavorname`)

1. Retrieve the iOS Distribution Certificate (in person) and the Provisioning Profiles (via Xcode, you must be part of our development team)
1. Update metadata (especially the release notes) in `fastlane/metadata` (fastlane will create a new version in iTunesConnect)
1. Optional: Create app screenshots via `fastlane make_screenshots`
1. Upload metadata via `fastlane upload_metadata`
1. Optional: Upload screenshots via `fastlane upload_screenschots`
1. Upload IPA via `fastlane release`
1. Wait until iTunesConnect has processed the build
1. Assign the build to the release manually
1. Submit the release to review manually
1. Create a github release (incl. git tag) for the release via `fastlane tag_release`
1. Refresh the dSYM files on Firebase for the current app version via `fastlane refresh_dsyms`
100 changes: 82 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
Xikolo iOS App
</h1>

<img align="center" src="assets/banner.png?raw=true" alt="xikolo-ios banner" width="933" />

<p align="center">
<img src="assets/banner.png?raw=true" alt="xikolo-ios banner" />
</p>

<p align="center">
iOS application for openHPI, openSAP, mooc.house, lernen.cloud and OpenWHO
iOS application for the HPI MOOC Platform
</p>

### Development toolchain
## Development Toolchain

- Xcode 11.5
- bundler: `gem install bundler`

Expand All @@ -21,25 +23,87 @@ The following tools will be installed via CocoaPods:
- [SwiftLint](https://github.com/realm/SwiftLint)
- [BartyCrouch](https://github.com/Flinesoft/BartyCrouch)

## How to get started
- clone this repository
- run `bundle install`
- run `bundle exec pod repo update` and `bundle exec pod install`
- run `cp -R ./iOS/Branding/openHPI/assets-ios-brand.xcassets ./iOS/assets-ios-brand.generated.xcassets`
- open xikolo-ios.xcworkspace in Xcode
- start one of the defined targets
## Contribute

Take a look at our [Contribution Guide](CONTRIBUTING.md) to learn about the key components, our development process, the tools we use, programming guidelines and more.

### Get Started

1. Clone this repository
1. Install development tools
```
bundle install
```
1. Update CocoaPods index & install dependencies
```
bundle exec pod repo update
bundle exec pod install
```
1. Copy initial branded app assets to prevent build errors
```
cp -R ./iOS/Branding/openHPI/assets-ios-brand.xcassets ./iOS/assets-ios-brand.generated.xcassets
```
1. Open `xikolo-ios.xcworkspace` (or simply `xed .` in the terminal)
1. Build and run one of the targets

### Setup Testing

1. Create the initial credentials file (to avoid build errors on the first test run)
```
cp iOS-UITests/Credentials.plist.dummy iOS-UITests/Credentials.plist
```
1. Create the default credentials file
```
cp iOS-UITests/Credentials.plist.dummy iOS-UITests/Credentials-default.plist
```
1. Optional: Create a brand specific credentials file
```
cp iOS-UITests/Credentials.plist.dummy iOS-UITests/Credentials-<BRAND_NAME>.plist
```
1. Enter your login credentials for testing in the respective credentials files

## Overall Architecture

For the overall architecture, we follow a plain MVC approach. However we make use of some reactive programming by using futures and promises provided by [BrightFutures](https://github.com/Thomvis/BrightFutures).

### Naming Schema

The application fetches multiple resources from the backend. For a `Resource`, all related classes follow most of the time the following naming schema.
- `Resource`: The respective CoreData model
- `ResourceListViewController`: The view controller listing multiple resources -- usually in a table or collection view
- `ResourceViewController`: The detail view controller for a single resource
- `ResourceHelper`: The controller resonsible for synchronizing the resources with the server
- `ResourceHelper+FetchRequests`: CoreData fetch requests for the resource

### Setup testing
- Create the initial credentials file `cp iOS-UITests/Credentials.plist.dummy iOS-UITests/Credentials.plist` (to avoid build errors on the first test run)
- Create the default credentials file `cp iOS-UITests/Credentials.plist.dummy iOS-UITests/Credentials-default.plist`
- To create a brand specific credentials plist `cp iOS-UITests/Credentials.plist.dummy iOS-UITests/Credentials-<BRAND_NAME>.plist`
- Enter your login credentials for testing in `Credentials-default.plist`
### Modules & Targets

## Contribute to _xikolo-ios_
Check out [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
To allow better code reusability, we restructured the codebase in multiple modules. For one, this reduces the application size as resources are not additionally bundled when used in an app extension. It also prevents you from going crazy by ticking hundreds of checkboxes for the target membership.
Important modules are listed below. If applicalble and neccesary, those modules can be further split up.

#### Commom

The `Common` module holds the core functionality of the app, which is required in all targets. It includes the CoreData models, API abstraction layer, common functionalities and generic helpers.

#### Stockpile

The `Stockpile` module is responsible for retrieving resources from the backend and synchronizing them with the local storage. It is capable of sending network requests depending on the protocol of the backend.

#### Binge

The `Binge` module provides a custom video player which in contrast to `AVPlayerViewController` allows entering the full-screen mode programmatically and provides controls for changing the playback rate.

#### iOS

The `iOS` target is the main application.

#### Today

The `Today` target provides the today app extension (widget in the today view, considered legacy in iOS 14 and later).

## Code of Conduct

Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).

## License

This project is licensed under the terms of the MIT license. See the [LICENSE](LICENSE) file.
36 changes: 36 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# How to Release a New Version of the Apps

You have to be part of our core dev team to do this.

## Prerequirements

1. To enable release via fastlane, create your copy of the Appfile
```
cp fastlane/Appfile.dummy fastlane/Appfile
```
Enter values for `apple_id` (your Apple developer account) and `itunes_connect_id` (your Apple account with access to AppStoreConnect). Those two could be the same Apple account.
1. Sensitive files are protected with [`git-crypt`](https://github.com/AGWA/git-crypt/). To compile release builds, [install](https://www.agwa.name/projects/git-crypt/) `git-crypt`:
```
brew install git-crypt
```
And unlock the encrypted files:
```
git-crypt unlock /path/to/xikolo-ios.key
```
The keyfile is managed by our core dev team and should never be made public or added to the repository.

## Release the Apps

There is a fastlane command for each step. One for all flavors and one for each flavor (suffix: `_flavorname`)

1. Retrieve the iOS Distribution Certificate (in person) and the Provisioning Profiles (via Xcode, you must be part of our development team)
1. Update metadata (especially the release notes) in `fastlane/metadata` (fastlane will create a new version in iTunesConnect)
1. Optional: Create app screenshots via `fastlane make_screenshots`
1. Upload metadata via `fastlane upload_metadata`
1. Optional: Upload screenshots via `fastlane upload_screenschots`
1. Upload IPA via `fastlane release`
1. Wait until iTunesConnect has processed the build
1. Assign the build to the release manually
1. Submit the release to review manually
1. Create a GitHub release (incl. git tag) for the release via `fastlane tag_release`
1. Refresh the dSYM files on Firebase for the current app version via `fastlane refresh_dsyms`
Binary file modified assets/banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 3e0ba85

Please sign in to comment.