A code generator for iOS
Project description
igen - A code generator for iOS app
Installation:
Install using pip:
Open Terminal and run:
$ pip3 install igen
Update:
$ pip3 install -U igen
or
$ pip3 uninstall igen
$ pip3 install igen --no-cache-dir
Uninstall:
$ pip3 uninstall igen
How to install pip3:
pip3 is already installed if you are using Python 3 (>=3.4)
In order to install Python 3, you need to install Homebrew, run the following command in Terminal:
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Then install Python 3:
$ brew install python
1. Create Template:
1.1. Base Template:
The Base Template contains necessary files for a screen using the Clean Architecture pattern.
Open Terminal, navigate to the folder you want to save the files and run:
$ igen template base <Scene_Name> [--window]
Options:
--window
: use UIWindow instead of UINavigationController in the Navigator.
The first time you use the template
command, you need to enter your project information:
Enter project name: Your Project
Enter developer name: Your Name
Enter company name: Your Company
Later, if you want to update the information you can run:
$ igen config project
Example:
$ igen template base Login
Output:
Successfully created files:
Login/LoginViewModel.swift
Login/LoginNavigator.swift
Login/LoginUseCase.swift
Login/LoginViewController.swift
Login/LoginAssembler.swift
Login/Test/LoginViewModelTests.swift
Login/Test/LoginUseCaseMock.swift
Login/Test/LoginNavigatorMock.swift
Login/Test/LoginViewControllerTests.swift
1.2. Skeleton Template:
To create a Clean Architecture skeleton project, run:
$ igen template skeleton <Folder_Name>
Example:
Run the following command in Terminal:
$ igen template skeleton DemoApp
Output:
Successfully created files:
DemoApp/Podfile
DemoApp/gitignore
DemoApp/Localizable.strings
DemoApp/pull_request_template.md
DemoApp/swiftlint.yml
DemoApp/DemoApp-Bridging-Header.h
DemoApp/Sources/UnitTestViewController.swift
DemoApp/Sources/AppDelegate.swift
DemoApp/Sources/Assembler.swift
DemoApp/Sources/Support/Utils.swift
DemoApp/Sources/Support/Extensions/UIViewController+.swift
DemoApp/Sources/Support/Extensions/UIViewController+Rx.swift
DemoApp/Sources/Data/Gateways/GatewaysAssembler.swift
DemoApp/Sources/Data/API/APIError.swift
DemoApp/Sources/Data/API/APIService.swift
DemoApp/Sources/Data/API/APIInput.swift
DemoApp/Sources/Data/API/APIOutput.swift
DemoApp/Sources/Config/APIUrls.swift
DemoApp/Sources/Scenes/App/AppAssembler.swift
DemoApp/Sources/Scenes/App/AppNavigator.swift
DemoApp/Sources/Scenes/App/AppUseCase.swift
DemoApp/Sources/Scenes/App/AppViewModel.swift
DemoApp/Sources/Scenes/Storyboards/Storyboards.swift
1.3. List Template:
The List Template shows a list of objects in a UITableView or a UICollectionView.
Copy the model to the pasteboard (clipboard) then run:
$ igen template list <Scene_Name> [--section] [--collection] [--window] [--paging]
Options:
--paging
: use pagination.
--section
: show the list with header sections.
--collection
: use UICollectionView instead of UITableView.
--window
: use UIWindow instead of UINavigationController in the Navigator.
Example:
Copy the model:
struct Product {
let id: Int
let name: String
let price: Double
}
then run:
$ igen template list ProductList
Output:
Successfully created files:
ProductList/ProductListViewModel.swift
ProductList/ProductItemViewModel.swift
ProductList/ProductListNavigator.swift
ProductList/ProductListUseCase.swift
ProductList/ProductListViewController.swift
ProductList/ProductCell.swift
ProductList/ProductListAssembler.swift
ProductList/Test/ProductListViewModelTests.swift
ProductList/Test/ProductListUseCaseMock.swift
ProductList/Test/ProductListNavigatorMock.swift
ProductList/Test/ProductListViewControllerTests.swift
ProductList/Test/ProductCellTests.swift
1.4. Detail Template:
The Detail Template shows details of an object in a UITableView.
Copy the model then run:
$ igen template detail <Scene_Name> [--static] [--window]
Options:
--static
: display details of the object in a static UITableViewController.
--window
: use UIWindow instead of UINavigationController in the Navigator.
Example:
Copy the model:
struct Product {
let id: Int
let name: String
let price: Double
}
then run:
$ igen template detail ProductDetail
Output:
Successfully created files:
ProductDetail/ProductDetailViewModel.swift
ProductDetail/ProductDetailNavigator.swift
ProductDetail/ProductDetailUseCase.swift
ProductDetail/ProductDetailViewController.swift
ProductDetail/ProductIdCell.swift
ProductDetail/ProductNameCell.swift
ProductDetail/ProductPriceCell.swift
ProductDetail/ProductDetailAssembler.swift
ProductDetail/Test/ProductDetailViewModelTests.swift
ProductDetail/Test/ProductDetailUseCaseMock.swift
ProductDetail/Test/ProductDetailNavigatorMock.swift
ProductDetail/Test/ProductDetailViewControllerTests.swift
ProductDetail/Test/ProductDetailCellsTests.swift
1.5. Form Input Template:
To create a form input template for a model, copy the model then run:
$ igen template form <Scene_Name> [--submit SUBMIT] [--dynamic] [--window]
Options:
--submit
: set the name of the submit action.
--dynamic
: use the dynamic form instead of the static form.
--window
: use UIWindow instead of UINavigationController in the Navigator.
Example:
Copy the model:
struct Product {
var id: Int
var name: String
var price: Double
}
then run:
$ igen template form CreateProduct --submit Create
Output:
Successfully created files:
CreateProduct/CreateProductAssembler.swift
CreateProduct/CreateProductNavigator.swift
CreateProduct/CreateProductViewModel.swift
CreateProduct/CreateProductUseCase.swift
CreateProduct/CreateProductViewController.swift
CreateProduct/Test/CreateProductUseCaseMock.swift
CreateProduct/Test/CreateProductNavigatorMock.swift
CreateProduct/Test/CreateProductViewModelTests.swift
CreateProduct/Test/CreateProductViewControllerTests.swift
1.6. Setting Template:
To create a setting template, copy the setting enum then run:
$ igen template setting <Scene_Name> [--section] [--window]
Options:
--section
: show the list with header sections.
--window
: use UIWindow instead of UINavigationController in the Navigator.
Example:
Copy the enum:
enum SettingMenu {
case about
case support
case facebook
case email
case rating
}
then run:
$ igen template setting Setting
Output:
Successfully created files:
Setting/SettingAssembler.swift
Setting/SettingNavigator.swift
Setting/SettingViewModel.swift
Setting/SettingUseCase.swift
Setting/SettingViewController.swift
Setting/SettingMenuCell.swift
Setting/Test/SettingUseCaseMock.swift
Setting/Test/SettingNavigatorMock.swift
Setting/Test/SettingViewModelTests.swift
Setting/Test/SettingViewControllerTests.swift
Setting/Test/SettingMenuCellTests.swift
1.7. Login template:
To create a login template, run:
$ igen template login <Scene_Name> [--window]
Options:
--window
: use UIWindow instead of UINavigationController in the Navigator.
Example:
Run:
$ igen template login Login
Output:
Successfully created files:
Login/LoginAssembler.swift
Login/LoginNavigator.swift
Login/LoginViewModel.swift
Login/LoginUseCase.swift
Login/LoginViewController.swift
Login/LoginDto.swift
Login/Test/LoginUseCaseMock.swift
Login/Test/LoginNavigatorMock.swift
Login/Test/LoginViewModelTests.swift
Login/Test/LoginViewControllerTests.swift
2. Create a mock class for a protocol/function:
Copy the protocol/function then run:
$ igen mock [-p]
Options:
-p
, --print
: print the result.
Example:
Copy the protocol:
protocol ProductsNavigatorType {
func toProducts()
func toProductDetail(product: Product)
func toEditProduct(_ product: Product) -> Driver<EditProductDelegate>
}
then run:
$ igen mock
Output:
The result has been copied to the pasteboard.
Content in the pasteboard:
final class ProductsNavigatorMock: ProductsNavigatorType {
// MARK: - toProducts
var toProductsCalled = false
func toProducts() {
toProductsCalled = true
}
// MARK: - toProductDetail
var toProductDetailCalled = false
func toProductDetail(product: Product) {
toProductDetailCalled = true
}
// MARK: - toEditProduct
var toEditProductCalled = false
var toEditProductReturnValue = Driver<EditProductDelegate>.empty()
func toEditProduct(_ product: Product) -> Driver<EditProductDelegate> {
toEditProductCalled = true
return toEditProductReturnValue
}
}
3. Create unit tests for a view model:
Copy the view model then run:
$ igen test [-p]
Options:
-p
, --print
: print the result.
Example:
Copy the view model:
struct LoginViewModel: ViewModel {
struct Input {
let usernameTrigger: Driver<String>
let passwordTrigger: Driver<String>
let loginTrigger: Driver<Void>
}
struct Output {
@Property var usernameValidationMessage = ""
@Property var passwordValidationMessage = ""
@Property var isLoginEnabled = true
@Property var isLoading = false
@Property var error: Error?
}
then run:
$ igen test
Output:
The result has been copied to the pasteboard.
Content in the pasteboard:
final class LoginViewModelTests: XCTestCase {
private var viewModel: LoginViewModel!
private var navigator: LoginNavigatorMock!
private var useCase: LoginUseCaseMock!
private var input: LoginViewModel.Input!
private var output: LoginViewModel.Output!
private var disposeBag: DisposeBag!
// Triggers
private let usernameTriggerTrigger = PublishSubject<String>()
private let passwordTriggerTrigger = PublishSubject<String>()
private let loginTriggerTrigger = PublishSubject<Void>()
override func setUp() {
super.setUp()
navigator = LoginNavigatorMock()
useCase = LoginUseCaseMock()
viewModel = LoginViewModel(navigator: navigator, useCase: useCase)
input = LoginViewModel.Input(
usernameTrigger: usernameTrigger.asDriverOnErrorJustComplete(),
passwordTrigger: passwordTrigger.asDriverOnErrorJustComplete(),
loginTrigger: loginTrigger.asDriverOnErrorJustComplete()
)
disposeBag = DisposeBag()
output = viewModel.transform(input, disposeBag: disposeBag)
}
func test_usernameTriggerTrigger_() {
// arrange
// act
// assert
XCTAssert(true)
}
func test_passwordTriggerTrigger_() {
// arrange
// act
// assert
XCTAssert(true)
}
func test_loginTriggerTrigger_() {
// arrange
// act
// assert
XCTAssert(true)
}
}
4. Create an initialize method for a class/struct:
Copy the class/struct then run the command:
$ igen init [-p]
Options:
-p
, --print
: print the result.
Example:
Copy the model:
struct Product {
var id: Int
var name: String
var price: Double
}
then run:
$ igen init
Output:
The result has been copied to the pasteboard.
Content in the pasteboard:
extension Product {
init() {
self.init(
id: 0,
name: "",
price: 0.0
)
}
}
5. Create models from JSON:
Copy the json then run the command:
$ igen json <Model_Name> [-p]
Options:
—-return-classes
: return classes instead of structs.
-p
, --print
: print the result.
Example:
Copy the json:
{
"id": 989,
"content": "Hello world!",
"is_read": false,
"created_at": "2018-06-29T17:15:36+09:00"
}
then run:
$ igen json Notice
Output:
The result has been copied to the pasteboard.
Content in the pasteboard:
struct Notice {
var id = 0
var content = ""
var isRead = false
var createdAt = Date()
}
extension Notice: Then { }
extension Notice: Mappable {
init?(map: Map) {
self.init()
}
mutating func mapping(map: Map) {
id <- map["id"]
content <- map["content"]
isRead <- map["is_read"]
createdAt <- (map["created_at"], DateTransform())
}
}
6. File header command:
To update files’ headers, run:
$ igen header [--file-name] [--project] [--developer] [--created-date] [--copyright-year] [--company] <File_Paths>
Options:
--file-name
: update file name.
--project
: update project.
--developer
: update developer.
--created-date
: update created date.
--copyright-year
: update copyright year.
--company
: update company.
If you don’t set any options, the tool will update all header information base on its configuration file.
Example:
Update the company and the developer in AppDelegate’s header.
$ igen header AppDelegate.swift --company --developer
You can use wildcard as well:
Update all Swift files:
$ igen header *.swift
Update all Swift files in the Domain folder and its child folders (recursive) :
$ igen header Domain/**/*.swift
7. Configuration:
7.1. Configure the project information:
To update the project information, run:
$ igen config project [--global]
Options:
--global
: global configuration.
7.2. View the configuration:
To view the configuration, run:
$ igen config [--global]
Options:
--global
: global configuration.
7.3. Update a configuration:
$ igen config key value [--global] [--unset]
Options:
--global
: global configuration.
--unset
: delete a configuration.
Configure the project id:
$ igen config project.id <Project_ID>
Use the special value @project
if you want to use the MD5 encoded project name as the project id.
$ igen config project.id @project
The project id will be used in file headers.
//
// AppDelegate.swift
// MGiGen (d18ea2a2902863a858af4f0e0911ed35)
//
// Created by Tuan Truong on 3/27/19.
// Copyright © 2019 Sun Asterisk. All rights reserved.
//
Configure the output path:
$ igen config output.path <Path>
Example:
Set the current working directory as the output path (relative path):
$ igen config output.path .
Set the desktop as the output path:
$ igen config output.path /Users/<Your_Name>/Desktop/
You can use a special value @here
to set the current working directory as the output path (absolute path):
$ igen config output.path @here
Other special values: @desktop
, @downloads
, @documents
7.4. View the available configurations:
To view the available configurations, run:
$ igen config keys
Output:
Available configuration keys:
project.name
project.developer
project.company
project.id
output.path
7.5. Delete the configuration file:
To delete the configuration file, run:
$ igen config delete [--global]
Options:
--global
: global configuration.
8. Install Xcode templates:
Install Clean Architecture templates for Xcode:
$ igen xcode install-templates
Uninstall templates:
$ igen xcode uninstall-templates
9. Other commands:
Run:
$ igen -h
Links:
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file igen-3.0.0.tar.gz
.
File metadata
- Download URL: igen-3.0.0.tar.gz
- Upload date:
- Size: 67.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.52.0 CPython/3.9.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4391774b37e0a0ff5bca75df9847b7bfb923146e860ab8ffac8eb91a0c1e9be7 |
|
MD5 | c8152ebf97c7a988442ae4a369e91215 |
|
BLAKE2b-256 | 7c39fefdf28daa2074af75a98dd63cab7d79448967ccd9deeddda114e05251af |
File details
Details for the file igen-3.0.0-py3-none-any.whl
.
File metadata
- Download URL: igen-3.0.0-py3-none-any.whl
- Upload date:
- Size: 116.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.52.0 CPython/3.9.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f60c371e22fa5343279fb25c833c156150ee8d29520809463d11794e78e501d6 |
|
MD5 | 515d635ca013262bc60c47d734af3316 |
|
BLAKE2b-256 | a06e9ec2e2d570f9d99a6b371990352c0461f3ac651ead65eb8eb998e4561581 |