1. This app runs on iPhone
2. Application is developed using Swift(v-5) language using Xcode(v-13.x) IDE
3. Deployment target is iOS 11.0
Using MVVM architecture for neat, modular code. Every Module with folders has its own MVVM structure
Making the use of following depencies
- SideMenuSwift (https://github.com/kukushi/SideMenu) for right side menu
- IQKeyboardManager (https://github.com/hackiftekhar/IQKeyboardManager) to handle the keyboard in scrollable content
- IQDropDownTextField (https://github.com/hackiftekhar/IQDropDownTextField) to have pickerview and datepicker in textfields
- SwipeCellKit (https://github.com/SwipeCellKit/SwipeCellKit) to handle swipe actions for transactions while tagging
Using Storyboards and nibs with Autolayouts to prepare the UI. Took the help of multiple storyboards for collaborative work to minimize the conflicts.
Make use of well defined and implemented dynamic form to create your forms. Prepare a json according to your requirement in the following format
{
"formFieldSections":[
{
"title": "Amount",
"displaySequence": 0,
"fields": [
{
"title": "Amount",
"placeholder": "$0.00",
"attributeName": "amount",
"displaySequence": 0,
"regex": "^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$",
"regexValidationMessage": "Please enter valid input for amount",
"type": "number",
"isEditable": true,
"isMandatory": true,
"validationMessage": "Please enter amount",
"parentField": "another field's attribute name to have child-parent dependency",
"config": {
"items": ["a", "b", "c"], // to supply dropdown values
"format": "dd/MM/yyy" // to supply date format if type is date
}
}
]
}],
"fieldValues":{
"amount": "1234"
}
}
Use "fieldValues" to supply default values.
- Drop a container view in the required viewcontroller, take a tableViewController and change class name to "DynamicFormViewController" and embed this in the container view.
- Declare a variable "dynamicForm" and make use of prepareForSegue function
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let dynamicForm = segue.destination as? DynamicFormViewController {
self.dynamicForm = dynamicForm
}
}
In viewDidLoad(),
JsonLoader.loadJson(filename: index == .zero ? "TransactionDetailForm" : "TransactionDetailFormPersonal", T: Form.self) { response in
self.dynamicForm?.formData = response
self.dynamicForm?.sourceViewController = self
self.dynamicForm?.updateFormDataWith(itemList: ["Software", "Real Estate", "Communications"], for: "businessCategory")
}
Load your local json files and get response accordingly by specifying required type
JsonLoader.loadJson(filename: "TransactionDetailForm", T: Form.self) { response in
// your code
}
titleLabel.setAttributes(type: .headerTitle)
nextButton.setAttributes(type: .primaryButton)
Refer ObjectAtttibuteManager.swift file for all types of UI control types
Note: Please set text before applying attributes
Subclass from this class to conform to Routable protocol which is very handy for navigation stack
A shortcut way to navigate to next screen
show(storyboard: .moreAboutYou, identifier: .moreAboutYou, configure: { (controller: MoreAboutYouViewController) in
// pass data from her
})
Reduce the pain of hardcoded values by specifying the variables here and use them
- Inter constants -
let kInt0 = 0
- Float constants -
let kFloat05 = 0.5
- Image constants -
let kDownArrowImage = "arrow.up.arrow.down"
- String constants -
let kOk = "OK"
- ViewController specific constants
Call the following function in AppDelegate to clear all cache
func clearCache() {
UserDefaults.didCompleteQuestionair = false
UserDefaults.shouldHideSummaryPopup = false
UserDefaults.didShowStartReviewScreen = false
GigiKeychainWrapper.standard.setUsername(nil)
}
Refer Gigi.json
file for all theme related attributes and add your own as per your requirement and update the ThemeModel.swift
file accordingly.
Using HelveticaNeueLTStd
fonts family. All the fonts are added in "Fonts" folder under "Resources"
static func hexColor(_ hex: String) -> UIColor
class func rgb(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat=1.0) -> UIColor
var dollarPattern: String
func validate(regex: String?) -> Bool
func convertDate(fromFormat: String) -> Date
var urlEncoded: String
func showAlert(_ message: String?, completion: (() -> ())? = nil)
func setTitle(_ title: String, andImage image: UIImage?)
to set the image and title on the UINavigationBarvar enableLargeTitles: Bool
to enable/disable large titlesfunc showActivityIndicator()
-
func applyTrailingConstant(equalTo: NSLayoutXAxisAnchor, constant: CGFloat) func applyLeftConstraint(equalTo: NSLayoutXAxisAnchor, constant: CGFloat) func applyRightConstraint(equalTo: NSLayoutXAxisAnchor, constant: CGFloat) func applyTopConstraint(equalTo: NSLayoutYAxisAnchor, constant: CGFloat) func applyBottomConstraint(equalTo: NSLayoutYAxisAnchor, constant: CGFloat) func applyHorizontalCenterConstraint(equalTo: NSLayoutXAxisAnchor) func applyVerticalCenterConstraint(equalTo: NSLayoutYAxisAnchor) ```
func resizeTo( size newSize:CGSize) -> UIImage
public func mask(with color: UIColor) -> UIImage
static func image(with name: String) -> UIImage
Use this function to maintain backward compatibility. If system image is not present it will pick the asset image ```func textEmbeded(string: String, isImageBeforeText: Bool = true, segFont: UIFont? = nil) -> UIImage
use this function to embed image and text anywhere ex: UISegmentedControl
- Use this logger to print anything which will only work in development not in live
GigiLogger.dPrint("Error!! Unable to parse \(filename).json")
func fillSeparator(_ left: CGFloat = .zero, right: CGFloat = .zero)
func registerCell(with identifiers: [String])
func registerHeaderFooterCell(with identifiers: [String])
var releaseVersionNumber: String?
var buildVersionNumber: String?
Mention all your notification name strings in this extension ex: static var textFieldShouldBeginEditing: Self { return .init(rawValue: "textFieldShouldBeginEditing") }
func toString(format: String?) -> String?
- Onboarding
- GetStarted
- Login
- MoreAboutYou
- Select Your Work
- Connect Financial Accounts
- Dashboard
- Home
- Accounts
- Transactions
- Accounts
- Activity
- Income
- Add Income
- Review Income
- Expense
- Add Expense
- Review Expenses
- Taxes
- Setup Tax
- Add Tax
- Tax Profile
- Income
- Gigs(Dummy screens)
- Home
- Utility Classes
- Common Search
- Reusable Slider
- Added a dummy barbutton item beside menu button on summary screen.
- An action sheet will be opened with all scenarios on clicking of the button.
- Select any option and the screen will be rendered accordingly. Note: This button should be removed once the APIs are integrated.