├── Catalyst-iOS-SDK-Sample-App ├── .DS_Store ├── Assets.xcassets │ ├── Contents.json │ ├── .DS_Store │ ├── DownArrow.imageset │ │ ├── DownArrow.png │ │ └── Contents.json │ ├── RightArrow.imageset │ │ ├── RightArrow.png │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── Resources │ ├── DownArrow.png │ └── RightArrow.png ├── AddARowCell.swift ├── Base.lproj │ └── LaunchScreen.storyboard ├── Info.plist ├── AppDelegate.swift ├── CommonUtil.swift ├── AddRowCell.swift ├── TasksViewController.swift ├── Field.swift ├── ForeignKeyField.swift ├── BooleanField.swift ├── TasksListViewController.swift ├── TaskViewController.swift ├── DetailViewController.swift ├── ListViewController.swift ├── HomeController.swift ├── ButtonFieldCell.swift ├── TextFieldCell.swift └── CreateController.swift ├── Catalyst-iOS-SDK-Sample-App.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ └── Catalyst-iOS-SDK-Sample-App.xcscheme └── project.pbxproj ├── .gitignore └── .gitignore └── Podfile /Catalyst-iOS-SDK-Sample-App/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoho/Catalyst-iOS-SDK-Sample-App/main/Catalyst-iOS-SDK-Sample-App/.DS_Store -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Resources/DownArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoho/Catalyst-iOS-SDK-Sample-App/main/Catalyst-iOS-SDK-Sample-App/Resources/DownArrow.png -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Resources/RightArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoho/Catalyst-iOS-SDK-Sample-App/main/Catalyst-iOS-SDK-Sample-App/Resources/RightArrow.png -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Assets.xcassets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoho/Catalyst-iOS-SDK-Sample-App/main/Catalyst-iOS-SDK-Sample-App/Assets.xcassets/.DS_Store -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Assets.xcassets/DownArrow.imageset/DownArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoho/Catalyst-iOS-SDK-Sample-App/main/Catalyst-iOS-SDK-Sample-App/Assets.xcassets/DownArrow.imageset/DownArrow.png -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Assets.xcassets/RightArrow.imageset/RightArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoho/Catalyst-iOS-SDK-Sample-App/main/Catalyst-iOS-SDK-Sample-App/Assets.xcassets/RightArrow.imageset/RightArrow.png -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore/.gitignore: -------------------------------------------------------------------------------- 1 | Example/Catalyst-iOS-SDK-Sample-App.xcworkspace/xcuserdata/ 2 | .DS_Store 3 | Example/Pods/Pods.xcodeproj/xcuserdata/ 4 | Catalyst-iOS-SDK-Sample-App/.DS_Store 5 | Catalyst-iOS-SDK-Sample-App.xcodeproj/xcuserdata/uma-6513.xcuserdatad 6 | Catalyst-iOS-SDK-Sample-App.xcodeproj/project.xcworkspace/xcuserdata/uma-6513.xcuserdatad/ 7 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'Catalyst-iOS-SDK-Sample-App' do 5 | # Comment the next line if you don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | pod 'ZCatalyst', :git => 'https://github.com/zoho/Catalyst-iOS-SDK.git', :tag => '2.0.1' 9 | 10 | # Pods for CatalystTestApp 11 | 12 | end 13 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Assets.xcassets/DownArrow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "DownArrow.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Assets.xcassets/RightArrow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "RightArrow.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/AddARowCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddARowCell.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 11/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class AddRowCell : UITableViewCell 12 | { 13 | 14 | static let identifier = "AddARowCell" 15 | 16 | override func awakeFromNib() 17 | { 18 | super.awakeFromNib() 19 | // Initialization code 20 | } 21 | 22 | override func setSelected( _ selected : Bool, animated : Bool ) 23 | { 24 | super.setSelected( selected, animated : animated ) 25 | // Configure the view for the selected state 26 | } 27 | 28 | static func dequeue( _ tableView : UITableView, indexPath : IndexPath, title : String ) -> AddRowCell 29 | { 30 | let cell = tableView.dequeueReusableCell( withIdentifier : <#T##String#>, for: <#T##IndexPath#>) 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleURLTypes 20 | 21 | 22 | CFBundleURLSchemes 23 | 24 | testAppConfig 25 | 26 | 27 | 28 | CFBundleVersion 29 | 1 30 | LSRequiresIPhoneOS 31 | 32 | UILaunchStoryboardName 33 | LaunchScreen 34 | UIRequiredDeviceCapabilities 35 | 36 | armv7 37 | 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UISupportedInterfaceOrientations~ipad 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationPortraitUpsideDown 48 | UIInterfaceOrientationLandscapeLeft 49 | UIInterfaceOrientationLandscapeRight 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 02/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ZCatalyst 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate 14 | { 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | self.window = UIWindow(frame: UIScreen.main.bounds) 20 | if let window = window 21 | { 22 | do 23 | { 24 | try ZCatalystApp.shared.initSDK( window : window, environment : .development ) 25 | } 26 | catch 27 | { 28 | print("Error occurred... \( error )") 29 | } 30 | 31 | window.rootViewController = UINavigationController( rootViewController : HomeController() ) 32 | window.makeKeyAndVisible() 33 | } 34 | return true 35 | } 36 | 37 | // MARK: UISceneSession Lifecycle 38 | 39 | func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { 40 | ZCatalystApp.shared.handleLoginRedirection( url, sourceApplication : sourceApplication, annotation: annotation ) 41 | return true 42 | } 43 | 44 | func application( _ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { 45 | let sourceapp = options[ UIApplication.OpenURLOptionsKey.sourceApplication ] 46 | ZCatalystApp.shared.handleLoginRedirection( url, sourceApplication : sourceapp as? String, annotation: "" ) 47 | return true 48 | } 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/CommonUtil.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CommonUtil.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 14/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Formatter 12 | { 13 | static let dateFormatter : DateFormatter = { 14 | let formatter = DateFormatter() 15 | formatter.locale = Locale( identifier : "en_US_POSIX" ) 16 | formatter.timeZone = TimeZone( secondsFromGMT : 0 ) 17 | formatter.dateFormat = "MMM dd, yyyy" 18 | return formatter 19 | }() 20 | 21 | static let dateFormatterWithTimeZone : DateFormatter = { 22 | let formatter = DateFormatter() 23 | formatter.dateFormat = "MMM dd, yyyy' at 'HH:mm" 24 | return formatter 25 | }() 26 | 27 | static let dateFormatterForAPI : DateFormatter = { 28 | let formatter = DateFormatter() 29 | formatter.dateFormat = "yyyy-MM-dd" 30 | return formatter 31 | }() 32 | 33 | static let dateFormatterWithTimeZoneForAPI : DateFormatter = { 34 | let formatter = DateFormatter() 35 | formatter.dateFormat = "yyyy-MM-dd' 'HH:mm:ss" 36 | return formatter 37 | }() 38 | } 39 | 40 | extension Date 41 | { 42 | var date : String 43 | { 44 | return Formatter.dateFormatter.string( from : self ) 45 | } 46 | 47 | var dateTime : String 48 | { 49 | return Formatter.dateFormatterWithTimeZone.string( from : self ) 50 | } 51 | 52 | var iso8601 : String 53 | { 54 | return Formatter.dateFormatterForAPI.string( from : self ) 55 | } 56 | 57 | var iso8601WithTimeZone : String 58 | { 59 | return Formatter.dateFormatterWithTimeZoneForAPI.string( from : self ) 60 | } 61 | } 62 | 63 | extension String 64 | { 65 | var date : Date? 66 | { 67 | return Formatter.dateFormatter.date( from : self ) 68 | } 69 | 70 | var dateTime : Date? 71 | { 72 | return Formatter.dateFormatterWithTimeZone.date( from : self ) 73 | } 74 | 75 | var dateFromISO8601 : Date? 76 | { 77 | return Formatter.dateFormatterForAPI.date( from : self ) // "Nov 14, 2017, 10:22 PM" 78 | } 79 | 80 | var dateFromISO8601WithTimeZone : Date? 81 | { 82 | return Formatter.dateFormatterWithTimeZoneForAPI.date( from : self ) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/AddRowCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddARowCell.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 11/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class AddRowCell : UITableViewCell 12 | { 13 | let button = UIButton() 14 | let cellPadding : CGFloat = 0 15 | var dataBuilder : CatalystDataBuilder? 16 | var tableName : String? 17 | static let identifier = "AddARowCell" 18 | 19 | override func awakeFromNib() 20 | { 21 | super.awakeFromNib() 22 | // Initialization code 23 | } 24 | 25 | override func setSelected( _ selected : Bool, animated : Bool ) 26 | { 27 | super.setSelected( selected, animated : animated ) 28 | // Configure the view for the selected state 29 | } 30 | 31 | static func dequeue( _ tableView : UITableView, indexPath : IndexPath, title : String, tableName : String, dataBuilder : CatalystDataBuilder, cellPadding : CGFloat ) -> AddRowCell 32 | { 33 | let cell = tableView.dequeueReusableCell( withIdentifier : AddRowCell.identifier, for : indexPath ) as? AddRowCell ?? AddRowCell() 34 | cell.tableName = tableName 35 | cell.dataBuilder = dataBuilder 36 | cell.constructCell() 37 | cell.button.setTitle( title, for : .normal ) 38 | return cell 39 | } 40 | 41 | func setConstraints() 42 | { 43 | button.leadingAnchor.constraint( equalTo : self.contentView.leadingAnchor, constant : cellPadding ).isActive = true 44 | button.trailingAnchor.constraint( equalTo : self.contentView.trailingAnchor, constant : cellPadding ).isActive = true 45 | button.topAnchor.constraint( equalTo : self.contentView.topAnchor, constant : cellPadding ).isActive = true 46 | button.bottomAnchor.constraint( equalTo : self.contentView.bottomAnchor, constant : cellPadding ).isActive = true 47 | } 48 | 49 | func constructCell() 50 | { 51 | for subview in self.contentView.subviews 52 | { 53 | subview.removeFromSuperview() 54 | } 55 | 56 | self.contentView.addSubview( button ) 57 | button.translatesAutoresizingMaskIntoConstraints = false 58 | button.setTitleColor( .systemBlue, for : .normal ) 59 | button.addTarget( self, action : #selector( navigate ), for : .touchUpInside ) 60 | setConstraints() 61 | } 62 | 63 | @objc func navigate() 64 | { 65 | if let dataBuilder = dataBuilder, let tableName = tableName 66 | { 67 | ( getCurrentViewController() as? UINavigationController )?.pushViewController( CreateController( tableName : tableName, row : nil, dataBuilder : dataBuilder ), animated : true ) 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App.xcodeproj/xcshareddata/xcschemes/Catalyst-iOS-SDK-Sample-App.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/TasksViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TasksViewController.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 04/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Catalyst 11 | 12 | class TasksListViewController : UITableViewController 13 | { 14 | var searchOptions : ZCatalystSearchOptions? 15 | var tasks = [ String? ]() 16 | 17 | init( searchOptions : ZCatalystSearchOptions? ) 18 | { 19 | self.searchOptions = searchOptions 20 | super.init( style : .plain ) 21 | self.getTasks() 22 | } 23 | 24 | required init?( coder : NSCoder ) 25 | { 26 | fatalError( "init( coder : ) has not been implemented" ) 27 | } 28 | 29 | override func viewDidLoad() 30 | { 31 | super.viewDidLoad() 32 | self.tableView.register( UITableViewCell.self, forCellReuseIdentifier : "Task" ) 33 | } 34 | 35 | // MARK: - Table view data source 36 | 37 | override func numberOfSections( in tableView : UITableView ) -> Int 38 | { 39 | return 1 40 | } 41 | 42 | override func tableView( _ tableView : UITableView, numberOfRowsInSection section : Int ) -> Int 43 | { 44 | return tasks.count 45 | } 46 | 47 | override func tableView( _ tableView : UITableView, cellForRowAt indexPath : IndexPath ) -> UITableViewCell 48 | { 49 | let cell = tableView.dequeueReusableCell( withIdentifier : "Task", for : indexPath ) 50 | cell.textLabel?.text = tasks[ indexPath.row ] 51 | return cell 52 | } 53 | 54 | // MARK: - Fetch data from Catalyst sdk 55 | 56 | func getTasks() 57 | { 58 | if let searchOptions = searchOptions 59 | { 60 | ZCatalystApp.shared.search( searchOptions : searchOptions ) { ( result ) in 61 | switch result 62 | { 63 | case .success( let result ) : 64 | let tasks = result.output[ "Tasks" ] as? [ [ String : Any ] ] 65 | if let tasks = tasks 66 | { 67 | for task in tasks 68 | { 69 | self.tasks.append( task[ "Title" ] as? String ) 70 | } 71 | } 72 | DispatchQueue.main.async { 73 | self.tableView.reloadData() 74 | } 75 | case .error( let error ) : 76 | print( "Error occurred >>> \( error )" ) 77 | } 78 | } 79 | } 80 | else 81 | { 82 | ZCatalystApp.shared.getDataStoreInstance().getTable( name : "Tasks" ) { ( result ) in 83 | switch result 84 | { 85 | case .success( let table ) : 86 | table.getRows { ( rowResult ) in 87 | switch rowResult 88 | { 89 | case .success( let rows ) : 90 | for row in rows 91 | { 92 | self.tasks.append( row.getValue( forKey : "Title" ) ) 93 | } 94 | DispatchQueue.main.async { 95 | self.tableView.reloadData() 96 | } 97 | case .error( let error ) : 98 | print( "Error occurred >>> \( error )" ) 99 | } 100 | } 101 | case .error( let error ) : 102 | print( "Error occurred >>> \( error )" ) 103 | } 104 | } 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/Field.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Field.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 09/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class Field : UITableViewCell 12 | { 13 | let background = UIView() 14 | let valueLabel = UILabel() 15 | let label = UILabel() 16 | var displayLabel = String() 17 | var value : String? 18 | var cellPadding : CGFloat = 0 19 | static var identifier = "FieldCell" 20 | 21 | override func awakeFromNib() 22 | { 23 | super.awakeFromNib() 24 | // Initialization code 25 | } 26 | 27 | override func setSelected( _ selected : Bool, animated : Bool ) 28 | { 29 | super.setSelected( selected, animated : animated ) 30 | } 31 | 32 | static func dequeue( _ tableView : UITableView, for indexPath : IndexPath, displayLabel : String, value : String?, cellPadding : CGFloat ) -> Field 33 | { 34 | let cell = tableView.dequeueReusableCell( withIdentifier : Field.identifier, for : indexPath ) as? Field ?? Field() 35 | cell.displayLabel = displayLabel 36 | cell.value = value 37 | cell.cellPadding = cellPadding 38 | cell.constructCell() 39 | return cell 40 | } 41 | 42 | func setConstraints() 43 | { 44 | background.leadingAnchor.constraint( equalTo : contentView.leadingAnchor ).isActive = true 45 | background.widthAnchor.constraint( equalTo : contentView.widthAnchor, multiplier : 0.4 ).isActive = true 46 | background.topAnchor.constraint( equalTo : contentView.topAnchor ).isActive = true 47 | background.bottomAnchor.constraint( equalTo : contentView.bottomAnchor ).isActive = true 48 | 49 | label.leadingAnchor.constraint( equalTo : contentView.leadingAnchor, constant : cellPadding ).isActive = true 50 | label.trailingAnchor.constraint( equalTo : background.trailingAnchor, constant : -cellPadding ).isActive = true 51 | label.centerYAnchor.constraint( equalTo : contentView.centerYAnchor ).isActive = true 52 | 53 | valueLabel.trailingAnchor.constraint( equalTo : self.contentView.trailingAnchor, constant : -cellPadding ).isActive = true 54 | valueLabel.leadingAnchor.constraint( equalTo : background.trailingAnchor, constant : cellPadding ).isActive = true 55 | valueLabel.centerYAnchor.constraint( equalTo : self.contentView.centerYAnchor ).isActive = true 56 | } 57 | 58 | func constructCell() 59 | { 60 | for subview in self.contentView.subviews 61 | { 62 | subview.removeFromSuperview() 63 | } 64 | for subview in background.subviews 65 | { 66 | subview.removeFromSuperview() 67 | } 68 | 69 | if #available( iOS 13.0, * ) 70 | { 71 | background.backgroundColor = .secondarySystemBackground 72 | } 73 | else 74 | { 75 | background.backgroundColor = UIColor( red : 0.98, green : 0.98, blue : 0.98, alpha : 1.0 ) 76 | } 77 | background.translatesAutoresizingMaskIntoConstraints = false 78 | self.contentView.addSubview( background ) 79 | 80 | label.translatesAutoresizingMaskIntoConstraints = false 81 | label.text = displayLabel 82 | label.font = UIFont.systemFont( ofSize : 14 ) 83 | label.textColor = .systemGray 84 | label.textAlignment = .right 85 | background.addSubview( label ) 86 | 87 | valueLabel.translatesAutoresizingMaskIntoConstraints = false 88 | valueLabel.text = value 89 | valueLabel.font = UIFont.systemFont( ofSize : 14 ) 90 | valueLabel.textColor = .systemGray 91 | valueLabel.textAlignment = .left 92 | self.contentView.addSubview( valueLabel ) 93 | 94 | setConstraints() 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/ForeignKeyField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ForeignKeyField.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 10/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ZCatalyst 11 | 12 | class ForeignKeyField : UITableViewCell 13 | { 14 | let background = UIView() 15 | let button = UIButton() 16 | let label = UILabel() 17 | var displayLabel = String() 18 | var value : String? 19 | var row : ZCatalystRow? 20 | var cellPadding : CGFloat = 0 21 | var dataBuilder : CatalystDataBuilder? 22 | static var identifier = "ForeignKeyCell" 23 | 24 | override func awakeFromNib() 25 | { 26 | super.awakeFromNib() 27 | // Initialization code 28 | } 29 | 30 | override func setSelected( _ selected : Bool, animated : Bool ) 31 | { 32 | super.setSelected( selected, animated : animated ) 33 | } 34 | 35 | static func dequeue( _ tableView : UITableView, for indexPath : IndexPath, displayLabel : String, value : String?, row : ZCatalystRow?, dataBuilder : CatalystDataBuilder, cellPadding : CGFloat ) -> ForeignKeyField 36 | { 37 | let cell = tableView.dequeueReusableCell( withIdentifier : BooleanField.identifier, for : indexPath ) as? ForeignKeyField ?? ForeignKeyField() 38 | cell.displayLabel = displayLabel 39 | cell.value = value 40 | cell.row = row 41 | cell.dataBuilder = dataBuilder 42 | cell.cellPadding = cellPadding 43 | cell.constructCell() 44 | return cell 45 | } 46 | 47 | func setConstraints() 48 | { 49 | background.leadingAnchor.constraint( equalTo : contentView.leadingAnchor ).isActive = true 50 | background.widthAnchor.constraint( equalTo : contentView.widthAnchor, multiplier : 0.4 ).isActive = true 51 | background.topAnchor.constraint( equalTo : contentView.topAnchor ).isActive = true 52 | background.bottomAnchor.constraint( equalTo : contentView.bottomAnchor ).isActive = true 53 | 54 | label.leadingAnchor.constraint( equalTo : contentView.leadingAnchor, constant : cellPadding ).isActive = true 55 | label.trailingAnchor.constraint( equalTo : background.trailingAnchor, constant : -cellPadding ).isActive = true 56 | label.centerYAnchor.constraint( equalTo : contentView.centerYAnchor ).isActive = true 57 | 58 | button.trailingAnchor.constraint( equalTo : self.contentView.trailingAnchor, constant : -cellPadding ).isActive = true 59 | button.leadingAnchor.constraint( equalTo : background.trailingAnchor, constant : cellPadding ).isActive = true 60 | button.centerYAnchor.constraint( equalTo : self.contentView.centerYAnchor ).isActive = true 61 | } 62 | 63 | func constructCell() 64 | { 65 | for subview in self.contentView.subviews 66 | { 67 | subview.removeFromSuperview() 68 | } 69 | for subview in background.subviews 70 | { 71 | subview.removeFromSuperview() 72 | } 73 | 74 | if #available( iOS 13.0, * ) 75 | { 76 | background.backgroundColor = .secondarySystemBackground 77 | } 78 | else 79 | { 80 | background.backgroundColor = UIColor( red : 0.98, green : 0.98, blue : 0.98, alpha : 1.0 ) 81 | } 82 | background.translatesAutoresizingMaskIntoConstraints = false 83 | self.contentView.addSubview( background ) 84 | 85 | label.translatesAutoresizingMaskIntoConstraints = false 86 | label.text = displayLabel 87 | label.font = UIFont.systemFont( ofSize : 14 ) 88 | label.textColor = .systemGray 89 | label.textAlignment = .right 90 | background.addSubview( label ) 91 | 92 | button.translatesAutoresizingMaskIntoConstraints = false 93 | button.setTitle( value, for : .normal ) 94 | button.setTitleColor( .systemBlue, for : .normal ) 95 | button.addTarget( self, action : #selector( navigate ), for : .touchUpInside ) 96 | self.contentView.addSubview( button ) 97 | 98 | setConstraints() 99 | } 100 | 101 | @objc func navigate() 102 | { 103 | if let id = row?.id, let builder = dataBuilder 104 | { 105 | ( getCurrentViewController() as? UINavigationController )?.view.endEditing( true ) 106 | ( getCurrentViewController() as? UINavigationController )?.pushViewController( DetailViewController( tableName : "Projects", rowId : id, dataBuilder : builder ), animated : true ) 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/BooleanField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BooleanField.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 10/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class BooleanField : UITableViewCell 12 | { 13 | let background = UIView() 14 | let uiSwitch = UISwitch() 15 | let label = UILabel() 16 | var displayLabel = String() 17 | var value = false 18 | var cellPadding : CGFloat = 0 19 | var rowDataDelegate : RowDataDelegate? 20 | static var identifier = "BooleanCell" 21 | 22 | override func awakeFromNib() 23 | { 24 | super.awakeFromNib() 25 | // Initialization code 26 | } 27 | 28 | override func setSelected( _ selected : Bool, animated : Bool ) 29 | { 30 | super.setSelected( selected, animated : animated ) 31 | } 32 | 33 | static func dequeue( _ tableView : UITableView, for indexPath : IndexPath, displayLabel : String, value : Bool?, rowDataDelegate : RowDataDelegate?, cellPadding : CGFloat ) -> BooleanField 34 | { 35 | let cell = tableView.dequeueReusableCell( withIdentifier : BooleanField.identifier, for : indexPath ) as? BooleanField ?? BooleanField() 36 | cell.displayLabel = displayLabel 37 | cell.value = value ?? false 38 | cell.rowDataDelegate = rowDataDelegate 39 | if let rowDataDelegate = rowDataDelegate 40 | { 41 | let val : Bool? = rowDataDelegate.getRow()?[ displayLabel ] 42 | cell.value = val ?? false 43 | } 44 | cell.cellPadding = cellPadding 45 | cell.constructCell() 46 | return cell 47 | } 48 | 49 | func setConstraints() 50 | { 51 | background.leadingAnchor.constraint( equalTo : contentView.leadingAnchor ).isActive = true 52 | background.widthAnchor.constraint( equalTo : contentView.widthAnchor, multiplier : 0.4 ).isActive = true 53 | background.topAnchor.constraint( equalTo : contentView.topAnchor ).isActive = true 54 | background.bottomAnchor.constraint( equalTo : contentView.bottomAnchor ).isActive = true 55 | 56 | label.leadingAnchor.constraint( equalTo : contentView.leadingAnchor, constant : cellPadding ).isActive = true 57 | label.trailingAnchor.constraint( equalTo : background.trailingAnchor, constant : -cellPadding ).isActive = true 58 | label.centerYAnchor.constraint( equalTo : contentView.centerYAnchor ).isActive = true 59 | 60 | uiSwitch.trailingAnchor.constraint( equalTo : self.contentView.trailingAnchor, constant : -cellPadding ).isActive = true 61 | uiSwitch.leadingAnchor.constraint( equalTo : background.trailingAnchor, constant : cellPadding ).isActive = true 62 | uiSwitch.centerYAnchor.constraint( equalTo : self.contentView.centerYAnchor ).isActive = true 63 | } 64 | 65 | func constructCell() 66 | { 67 | for subview in self.contentView.subviews 68 | { 69 | subview.removeFromSuperview() 70 | } 71 | for subview in background.subviews 72 | { 73 | subview.removeFromSuperview() 74 | } 75 | 76 | if #available( iOS 13.0, * ) 77 | { 78 | background.backgroundColor = .secondarySystemBackground 79 | } 80 | else 81 | { 82 | background.backgroundColor = UIColor( red : 0.98, green : 0.98, blue : 0.98, alpha : 1.0 ) 83 | } 84 | background.translatesAutoresizingMaskIntoConstraints = false 85 | self.contentView.addSubview( background ) 86 | 87 | label.translatesAutoresizingMaskIntoConstraints = false 88 | label.text = displayLabel 89 | label.font = UIFont.systemFont( ofSize : 14 ) 90 | label.textColor = .systemGray 91 | label.textAlignment = .right 92 | background.addSubview( label ) 93 | 94 | uiSwitch.translatesAutoresizingMaskIntoConstraints = false 95 | if rowDataDelegate == nil 96 | { 97 | uiSwitch.isUserInteractionEnabled = false 98 | } 99 | else 100 | { 101 | uiSwitch.isUserInteractionEnabled = true 102 | } 103 | self.contentView.addSubview( uiSwitch ) 104 | if value 105 | { 106 | uiSwitch.setOn( true, animated : false ) 107 | } 108 | else 109 | { 110 | uiSwitch.setOn( false, animated : false ) 111 | } 112 | uiSwitch.addTarget( self, action : #selector( switchChanged( _ : ) ), for: .valueChanged ) 113 | 114 | setConstraints() 115 | } 116 | 117 | @objc func switchChanged( _ sender : UISwitch ) 118 | { 119 | if sender.isOn 120 | { 121 | rowDataDelegate?.setRowData( for : displayLabel, value : true ) 122 | } 123 | else 124 | { 125 | rowDataDelegate?.setRowData( for : displayLabel, value : false ) 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/TasksListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TasksViewController.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 04/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Catalyst 11 | 12 | class ListViewController : UITableViewController 13 | { 14 | var tableName : String 15 | var searchOptions : ZCatalystSearchOptions? 16 | let dataBuilder : CatalystDataBuilder 17 | var tasks : [ [ String : Any? ] ]? 18 | var rows : [ ZCatalystRow ]? 19 | 20 | init( tableName : String searchOptions : ZCatalystSearchOptions?, dataBuilder : CatalystDataBuilder ) 21 | { 22 | self.searchOptions = searchOptions 23 | self.dataBuilder = dataBuilder 24 | super.init( style : .plain ) 25 | self.getTasks() 26 | } 27 | 28 | required init?( coder : NSCoder ) 29 | { 30 | fatalError( "init( coder : ) has not been implemented" ) 31 | } 32 | 33 | override func viewDidLoad() 34 | { 35 | super.viewDidLoad() 36 | self.tableView.register( UITableViewCell.self, forCellReuseIdentifier : "Task" ) 37 | self.tableView.register( AddRowCell.self, forCellReuseIdentifier : AddRowCell.identifier ) 38 | } 39 | 40 | // MARK: - Table view data source 41 | 42 | override func numberOfSections( in tableView : UITableView ) -> Int 43 | { 44 | return 1 45 | } 46 | 47 | override func tableView( _ tableView : UITableView, numberOfRowsInSection section : Int ) -> Int 48 | { 49 | return tasks.count + 1 50 | } 51 | 52 | override func tableView( _ tableView : UITableView, cellForRowAt indexPath : IndexPath ) -> UITableViewCell 53 | { 54 | if indexPath.row == 0 55 | { 56 | let cell = AddRowCell.dequeue( self.tableView, indexPath : indexPath, title : "+ Add a Task", cellPadding : self.view.bounds.width * 0.01 ) 57 | return cell 58 | } 59 | else 60 | { 61 | let cell = tableView.dequeueReusableCell( withIdentifier : "Task", for : indexPath ) 62 | cell.textLabel?.text = tasks[ indexPath.row - 1 ][ "Title" ] as? String 63 | return cell 64 | } 65 | } 66 | 67 | override func tableView( _ tableView : UITableView, didSelectRowAt indexPath : IndexPath ) 68 | { 69 | if let idStr = tasks[ indexPath.row ][ "ROWID" ] as? String, let id = Int64( idStr ) 70 | { 71 | self.navigationController?.pushViewController( DetailViewController( tableName : "Tasks", rowId : id, dataBuilder : dataBuilder ), animated : true ) 72 | } 73 | else if let id = tasks[ indexPath.row ][ "ROWID" ] as? Int64 74 | { 75 | self.navigationController?.pushViewController( DetailViewController( tableName : "Tasks", rowId : id, dataBuilder : dataBuilder ), animated : true ) 76 | } 77 | } 78 | 79 | // MARK: - Fetch data from Catalyst sdk 80 | 81 | func getTasks() 82 | { 83 | if let searchOptions = searchOptions 84 | { 85 | ZCatalystApp.shared.search( searchOptions : searchOptions ) { ( result ) in 86 | switch result 87 | { 88 | case .success( let result ) : 89 | if let tasks = result.output[ "Tasks" ] as? [ [ String : Any ] ] 90 | { 91 | self.tasks = tasks 92 | } 93 | DispatchQueue.main.async { 94 | self.tableView.reloadData() 95 | } 96 | case .error( let error ) : 97 | print( "Error occurred >>> \( error )" ) 98 | } 99 | } 100 | } 101 | else 102 | { 103 | ZCatalystApp.shared.getDataStoreInstance().getTable( name : "Tasks" ) { ( result ) in 104 | switch result 105 | { 106 | case .success( let table ) : 107 | table.getRows { ( rowResult ) in 108 | switch rowResult 109 | { 110 | case .success( let rows ) : 111 | for row in rows 112 | { 113 | self.tasks.append( row.getData() ) 114 | } 115 | DispatchQueue.main.async { 116 | self.tableView.reloadData() 117 | self.dataBuilder.setTask( table : table ) 118 | self.dataBuilder.setTasks( rows ) 119 | } 120 | case .error( let error ) : 121 | print( "Error occurred >>> \( error )" ) 122 | } 123 | } 124 | case .error( let error ) : 125 | print( "Error occurred >>> \( error )" ) 126 | } 127 | } 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/TaskViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TaskViewController.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 08/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Catalyst 11 | 12 | class DetailViewController : UITableViewController 13 | { 14 | var columns : [ ZCatalystColumn ] = [ ZCatalystColumn ]() 15 | var task : ZCatalystRow? 16 | var cellPadding : CGFloat = 0 17 | 18 | init( task : ZCatalystRow? ) 19 | { 20 | self.task = task 21 | super.init( style : .plain ) 22 | if let homeController = self.navigationController?.viewControllers[ 0 ] as? HomeController, let table = homeController.task 23 | { 24 | self.getColumns( from : table ) 25 | } 26 | else 27 | { 28 | self.getTable() 29 | } 30 | } 31 | 32 | init( id : Int64 ) 33 | { 34 | super.init( style : .plain ) 35 | if let homeController = self.navigationController?.viewControllers[ 0 ] as? HomeController, let table = homeController.task 36 | { 37 | self.getColumns( from : table ) 38 | self.getRow( with : id, from : table ) 39 | } 40 | else 41 | { 42 | self.getTable( rowId : id ) 43 | } 44 | } 45 | 46 | required init?( coder : NSCoder ) 47 | { 48 | fatalError( "init( coder : ) has not been implemented" ) 49 | } 50 | 51 | override func viewDidLoad() 52 | { 53 | super.viewDidLoad() 54 | self.tableView.register( UITableViewCell.self, forCellReuseIdentifier : "TaskDetail" ) 55 | 56 | self.tableView.register( Field.self, forCellReuseIdentifier : Field.identifier ) 57 | self.tableView.register( BooleanField.self, forCellReuseIdentifier : BooleanField.identifier ) 58 | self.cellPadding = self.view.bounds.width * 0.01 59 | 60 | tableView.tableFooterView = nil 61 | } 62 | 63 | // MARK: - Table view data source 64 | 65 | override func numberOfSections( in tableView : UITableView ) -> Int 66 | { 67 | return 1 68 | } 69 | 70 | override func tableView( _ tableView : UITableView, numberOfRowsInSection section : Int ) -> Int 71 | { 72 | return columns.count 73 | } 74 | 75 | override func tableView( _ tableView : UITableView, cellForRowAt indexPath : IndexPath ) -> UITableViewCell 76 | { 77 | if columns[ indexPath.row ].dataType == .boolean 78 | { 79 | let value : Bool? = task?[ columns[ indexPath.row ].name ] 80 | let cell = BooleanField.dequeue( self.tableView, for : indexPath, displayLabel : columns[ indexPath.row ].name, value : value, cellPadding : cellPadding ) 81 | return cell 82 | } 83 | else 84 | { 85 | let value : String? = task?[ columns[ indexPath.row ].name ] 86 | let cell = Field.dequeue( self.tableView, for : indexPath, displayLabel : columns[ indexPath.row ].name, value : value, cellPadding : cellPadding ) 87 | return cell 88 | } 89 | } 90 | 91 | // MARK: - Fetch data from Catalyst sdk 92 | 93 | func getTable( rowId : Int64? = nil ) 94 | { 95 | ZCatalystApp.shared.getDataStoreInstance().getTable( name : "Tasks") { ( result ) in 96 | switch result 97 | { 98 | case .success( let table ) : 99 | self.getColumns( from : table ) 100 | if let rowId = rowId 101 | { 102 | self.getRow( with : rowId, from : table ) 103 | } 104 | DispatchQueue.main.async 105 | { 106 | if let homeController = self.navigationController?.viewControllers[ 0 ] as? HomeController, let table = homeController.task 107 | { 108 | homeController.task = table 109 | } 110 | } 111 | case .error( let error ) : 112 | print( "Error occurred >>> \( error )" ) 113 | } 114 | } 115 | } 116 | 117 | func getColumns( from table : ZCatalystTable ) 118 | { 119 | table.getColumns { ( result ) in 120 | switch result 121 | { 122 | case .success( let columns ) : 123 | self.columns = columns 124 | DispatchQueue.main.async 125 | { 126 | self.tableView.reloadData() 127 | } 128 | case .error( let error ) : 129 | print( "Error occurred >>> \( error )" ) 130 | } 131 | } 132 | } 133 | 134 | func getRow( with id : Int64, from table : ZCatalystTable ) 135 | { 136 | table.getRow( id : id ) { ( result ) in 137 | switch result 138 | { 139 | case .success( let row ) : 140 | self.task = row 141 | DispatchQueue.main.async 142 | { 143 | self.tableView.reloadData() 144 | } 145 | case .error( let error ) : 146 | print( "Error occurred >>> \( error )" ) 147 | } 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/DetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TaskViewController.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 08/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ZCatalyst 11 | 12 | class DetailViewController : UITableViewController 13 | { 14 | let tableName : String 15 | let rowId : Int64 16 | let dataBuilder : CatalystDataBuilder 17 | var columns : [ ZCatalystColumn ] = [ ZCatalystColumn ]() 18 | var row : ZCatalystRow? 19 | var cellPadding : CGFloat = 5 20 | var attachmentName : String? 21 | 22 | init( tableName : String, rowId : Int64, dataBuilder : CatalystDataBuilder ) 23 | { 24 | self.tableName = tableName 25 | self.dataBuilder = dataBuilder 26 | self.rowId = rowId 27 | super.init( style : .plain ) 28 | self.configureData() 29 | } 30 | 31 | func configureData() 32 | { 33 | if tableName == "Tasks" 34 | { 35 | if let table = dataBuilder.getData().getTask() 36 | { 37 | if let columns = dataBuilder.getData().getTaskColumns() 38 | { 39 | self.columns = columns 40 | } 41 | else 42 | { 43 | getColumns( from : table ) 44 | } 45 | if let rows = dataBuilder.getData().getTasks() 46 | { 47 | for row in rows 48 | { 49 | if row.id == rowId 50 | { 51 | self.row = row 52 | } 53 | } 54 | if self.row == nil 55 | { 56 | getRow( with : rowId, from : table ) 57 | } 58 | } 59 | } 60 | else 61 | { 62 | getTable( tableName : tableName, rowId : rowId ) 63 | } 64 | } 65 | else if tableName == "Projects" 66 | { 67 | if let table = dataBuilder.getData().getProject() 68 | { 69 | if let columns = dataBuilder.getData().getProjectColumns() 70 | { 71 | self.columns = columns 72 | } 73 | else 74 | { 75 | getColumns( from : table ) 76 | } 77 | if let rows = dataBuilder.getData().getProjects() 78 | { 79 | for row in rows 80 | { 81 | if row.id == rowId 82 | { 83 | self.row = row 84 | } 85 | } 86 | if self.row == nil 87 | { 88 | getRow( with : rowId, from : table ) 89 | } 90 | } 91 | } 92 | else 93 | { 94 | getTable( tableName : tableName, rowId : rowId ) 95 | } 96 | } 97 | } 98 | 99 | required init?( coder : NSCoder ) 100 | { 101 | fatalError( "init( coder : ) has not been implemented" ) 102 | } 103 | 104 | override func viewDidLoad() 105 | { 106 | super.viewDidLoad() 107 | 108 | self.tableView.register( Field.self, forCellReuseIdentifier : Field.identifier ) 109 | self.tableView.register( BooleanField.self, forCellReuseIdentifier : BooleanField.identifier ) 110 | self.tableView.register( ForeignKeyField.self, forCellReuseIdentifier : ForeignKeyField.identifier ) 111 | self.tableView.register( ButtonFieldCell.self, forCellReuseIdentifier : ButtonFieldCell.identifier ) 112 | 113 | tableView.tableFooterView = nil 114 | tableView.allowsSelection = false 115 | 116 | let title : String? = row?[ "Title" ] 117 | self.navigationItem.title = title 118 | 119 | let editButton = UIBarButtonItem( title : "Edit", style : .plain, target : self, action : #selector( edit ) ) 120 | self.navigationItem.setRightBarButton( editButton, animated : true ) 121 | } 122 | 123 | override func viewWillAppear( _ animated : Bool ) 124 | { 125 | super.viewWillAppear( animated ) 126 | self.configureData() 127 | self.tableView.reloadData() 128 | } 129 | 130 | // MARK: - Table view data source 131 | 132 | override func numberOfSections( in tableView : UITableView ) -> Int 133 | { 134 | return 1 135 | } 136 | 137 | override func tableView( _ tableView : UITableView, numberOfRowsInSection section : Int ) -> Int 138 | { 139 | return columns.count 140 | } 141 | 142 | override func tableView( _ tableView : UITableView, cellForRowAt indexPath : IndexPath ) -> UITableViewCell 143 | { 144 | if columns[ indexPath.row ].dataType == .boolean 145 | { 146 | let value : Bool? = row?[ columns[ indexPath.row ].name ] 147 | let cell = BooleanField.dequeue( self.tableView, for : indexPath, displayLabel : columns[ indexPath.row ].name, value : value, rowDataDelegate : nil, cellPadding : cellPadding ) 148 | return cell 149 | } 150 | else if columns[ indexPath.row ].dataType == .foreignKey 151 | { 152 | let projId : String? = row?[ columns[ indexPath.row ].name ] 153 | if let projects = dataBuilder.getData().getProjects(), let projId = projId 154 | { 155 | for project in projects 156 | { 157 | if project.id == Int64( projId ) 158 | { 159 | let value : String? = project[ "Title" ] 160 | let cell = ForeignKeyField.dequeue( self.tableView, for : indexPath, displayLabel : columns[ indexPath.row ].name, value : value, row : project, dataBuilder : dataBuilder, cellPadding : cellPadding ) 161 | return cell 162 | } 163 | } 164 | } 165 | let cell = ForeignKeyField.dequeue( self.tableView, for : indexPath, displayLabel : columns[ indexPath.row ].name, value : nil, row : nil, dataBuilder : dataBuilder, cellPadding : cellPadding ) 166 | return cell 167 | } 168 | else if columns[ indexPath.row ].name == "Attachment" 169 | { 170 | let id : String? = row?.getValue( forKey : "Attachment" ) 171 | if let id = id, let attachmentId = Int64( id ) 172 | { 173 | if let file = dataBuilder.getData().getFile( id : attachmentId ) 174 | { 175 | self.attachmentName = file.name 176 | } 177 | else 178 | { 179 | if let folder = dataBuilder.getData().getFolder() 180 | { 181 | folder.getFile( fileId : attachmentId) { ( result ) in 182 | switch result 183 | { 184 | case .success( let file ) : 185 | self.dataBuilder.addFile( file ) 186 | self.attachmentName = file.name 187 | DispatchQueue.main.async { 188 | self.tableView.reloadRows( at : [ indexPath ], with : .automatic ) 189 | } 190 | case .error( let error ) : 191 | print( "Error occurred >>> \( error )" ) 192 | } 193 | } 194 | } 195 | else 196 | { 197 | ZCatalystApp.shared.getFileStoreInstance().getFolder( id : 2823000000006561 ) { ( folderResult ) in 198 | switch folderResult 199 | { 200 | case .success( let folder ) : 201 | self.dataBuilder.setFolder( folder : folder ) 202 | folder.getFile( fileId : attachmentId) { ( result ) in 203 | switch result 204 | { 205 | case .success( let file ) : 206 | self.dataBuilder.addFile( file ) 207 | self.attachmentName = file.name 208 | DispatchQueue.main.async { 209 | self.tableView.reloadRows( at : [ indexPath ], with : .automatic ) 210 | } 211 | case .error( let error ) : 212 | print( "Error occurred >>> \( error )" ) 213 | } 214 | } 215 | case .error( let error ) : 216 | print( "Error occurred >>> \( error )" ) 217 | } 218 | } 219 | } 220 | } 221 | } 222 | let cell = ButtonFieldCell.dequeue( tableView, for : indexPath, displayLabel : columns[ indexPath.row ].name, attachmentName : attachmentName, dataBuilder : dataBuilder, rowDataDelegate : self, isReadOnly : true, cellPadding : cellPadding ) 223 | return cell 224 | } 225 | else 226 | { 227 | let value : String? = row?[ columns[ indexPath.row ].name ] 228 | let cell = Field.dequeue( self.tableView, for : indexPath, displayLabel : columns[ indexPath.row ].name, value : value, cellPadding : cellPadding ) 229 | return cell 230 | } 231 | } 232 | 233 | @objc func edit() 234 | { 235 | self.navigationController?.pushViewController( CreateController( tableName : tableName, row : row, dataBuilder : dataBuilder ), animated : true ) 236 | } 237 | 238 | // MARK: - Fetch data from Catalyst sdk 239 | 240 | func getTable( tableName : String, rowId : Int64? = nil ) 241 | { 242 | ZCatalystApp.shared.getDataStoreInstance().getTable( name : tableName ) { ( result ) in 243 | switch result 244 | { 245 | case .success( let table ) : 246 | self.getColumns( from : table ) 247 | if let rowId = rowId 248 | { 249 | self.getRow( with : rowId, from : table ) 250 | } 251 | if tableName == "Tasks" 252 | { 253 | self.dataBuilder.setTask( table : table ) 254 | } 255 | else if tableName == "Projects" 256 | { 257 | self.dataBuilder.setProject( table : table ) 258 | } 259 | case .error( let error ) : 260 | print( "Error occurred >>> \( error )" ) 261 | } 262 | } 263 | } 264 | 265 | func getColumns( from table : ZCatalystTable ) 266 | { 267 | table.getColumns { ( result ) in 268 | switch result 269 | { 270 | case .success( let columns ) : 271 | self.columns = columns 272 | self.dataBuilder.setColumns( columns, for : table ) 273 | DispatchQueue.main.async 274 | { 275 | self.tableView.reloadData() 276 | } 277 | case .error( let error ) : 278 | print( "Error occurred >>> \( error )" ) 279 | } 280 | } 281 | } 282 | 283 | func getRow( with id : Int64, from table : ZCatalystTable ) 284 | { 285 | table.getRow( id : id ) { ( result ) in 286 | switch result 287 | { 288 | case .success( let row ) : 289 | self.row = row 290 | DispatchQueue.main.async 291 | { 292 | self.tableView.reloadData() 293 | } 294 | case .error( let error ) : 295 | print( "Error occurred >>> \( error )" ) 296 | } 297 | } 298 | } 299 | } 300 | 301 | extension DetailViewController : RowDataDelegate 302 | { 303 | func getRow() -> ZCatalystRow? 304 | { 305 | return row 306 | } 307 | 308 | func setRowData( for columnName : String, value : Any? ) 309 | { 310 | } 311 | 312 | func getAttachmentURL() -> URL? 313 | { 314 | return nil 315 | } 316 | 317 | func setAttachmentURL(_ url: URL?) 318 | { 319 | } 320 | 321 | func getAttachmentName() -> String? 322 | { 323 | return attachmentName 324 | } 325 | 326 | func setAttachmentName( _ name : String? ) 327 | { 328 | self.attachmentName = name 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/ListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TasksViewController.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 04/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ZCatalyst 11 | 12 | class ListViewController : UITableViewController 13 | { 14 | var tableName : String 15 | var searchOptions : ZCatalystSearchOptions? 16 | let dataBuilder : CatalystDataBuilder 17 | var filteredRows : [ [ String : Any? ] ]? 18 | var rows : [ ZCatalystRow ]? 19 | var textField : UITextField? 20 | var displayLabel : String? 21 | var rowDataDelegate : RowDataDelegate? 22 | 23 | 24 | init( tableName : String, searchOptions : ZCatalystSearchOptions?, dataBuilder : CatalystDataBuilder ) 25 | { 26 | self.tableName = tableName 27 | self.searchOptions = searchOptions 28 | self.dataBuilder = dataBuilder 29 | super.init( style : .plain ) 30 | self.configureData() 31 | } 32 | 33 | func configureData() 34 | { 35 | if searchOptions == nil 36 | { 37 | if tableName == "Tasks" 38 | { 39 | if let table = dataBuilder.getData().getTask() 40 | { 41 | if let rows = dataBuilder.getData().getTasks() 42 | { 43 | self.rows = rows 44 | } 45 | else 46 | { 47 | self.getRows( from : table ) 48 | } 49 | } 50 | else 51 | { 52 | getTable() 53 | } 54 | } 55 | else 56 | { 57 | if let table = dataBuilder.getData().getProject() 58 | { 59 | if let rows = dataBuilder.getData().getProjects() 60 | { 61 | self.rows = rows 62 | } 63 | else 64 | { 65 | self.getRows( from : table ) 66 | } 67 | } 68 | else 69 | { 70 | getTable() 71 | } 72 | } 73 | } 74 | else 75 | { 76 | getRowsFromSearch() 77 | } 78 | } 79 | 80 | required init?( coder : NSCoder ) 81 | { 82 | fatalError( "init( coder : ) has not been implemented" ) 83 | } 84 | 85 | override func viewDidLoad() 86 | { 87 | super.viewDidLoad() 88 | self.tableView.register( UITableViewCell.self, forCellReuseIdentifier : "Task" ) 89 | self.tableView.register( AddRowCell.self, forCellReuseIdentifier : AddRowCell.identifier ) 90 | } 91 | 92 | override func viewWillAppear(_ animated: Bool) { 93 | super.viewWillAppear( animated ) 94 | self.configureData() 95 | self.tableView.reloadData() 96 | } 97 | 98 | // MARK: - Table view data source 99 | 100 | override func numberOfSections( in tableView : UITableView ) -> Int 101 | { 102 | return 1 103 | } 104 | 105 | override func tableView( _ tableView : UITableView, numberOfRowsInSection section : Int ) -> Int 106 | { 107 | if let filteredRows = filteredRows 108 | { 109 | return filteredRows.count + 1 110 | } 111 | if let rows = rows 112 | { 113 | return rows.count + 1 114 | } 115 | return 0 116 | } 117 | 118 | override func tableView( _ tableView : UITableView, cellForRowAt indexPath : IndexPath ) -> UITableViewCell 119 | { 120 | if indexPath.row == 0 121 | { 122 | if tableName == "Tasks" 123 | { 124 | let cell = AddRowCell.dequeue( self.tableView, indexPath : indexPath, title : "+ Add a Task", tableName : "Tasks", dataBuilder : dataBuilder, cellPadding : self.view.bounds.width * 0.01 ) 125 | return cell 126 | } 127 | else 128 | { 129 | let cell = AddRowCell.dequeue( self.tableView, indexPath : indexPath, title : "+ Add a Project", tableName : "Projects", dataBuilder : dataBuilder, cellPadding : self.view.bounds.width * 0.01 ) 130 | return cell 131 | } 132 | } 133 | else 134 | { 135 | if let filteredRows = filteredRows 136 | { 137 | let cell = tableView.dequeueReusableCell( withIdentifier : "Task", for : indexPath ) 138 | cell.textLabel?.text = filteredRows[ indexPath.row - 1 ][ "Title" ] as? String 139 | return cell 140 | } 141 | else 142 | { 143 | let title : String? = rows?[ indexPath.row - 1 ][ "Title" ] 144 | let cell = tableView.dequeueReusableCell( withIdentifier : "Task", for : indexPath ) 145 | cell.textLabel?.text = title 146 | return cell 147 | } 148 | } 149 | } 150 | 151 | override func tableView( _ tableView : UITableView, didSelectRowAt indexPath : IndexPath ) 152 | { 153 | if let textField = textField, let rowDataDelegate = rowDataDelegate, let displayLabel = displayLabel, let id = rows?[ indexPath.row - 1 ].id 154 | { 155 | let title : String? = rows?[ indexPath.row - 1 ][ "Title" ] 156 | textField.text = title 157 | rowDataDelegate.setRowData( for : displayLabel, value : id ) 158 | self.navigationController?.popViewController( animated : true ) 159 | textField.endEditing( true ) 160 | } 161 | else 162 | { 163 | if let filteredRows = filteredRows, let idStr = filteredRows[ indexPath.row - 1 ][ "ROWID" ] as? String, let id = Int64( idStr ) 164 | { 165 | self.navigationController?.pushViewController( DetailViewController( tableName : "Tasks", rowId : id, dataBuilder : dataBuilder ), animated : true ) 166 | } 167 | else if let id = rows?[ indexPath.row - 1 ].id 168 | { 169 | self.navigationController?.pushViewController( DetailViewController( tableName : "Tasks", rowId : id, dataBuilder : dataBuilder ), animated : true ) 170 | } 171 | } 172 | } 173 | 174 | override func tableView( _ tableView : UITableView, canEditRowAt indexPath : IndexPath ) -> Bool 175 | { 176 | if indexPath.row != 0 177 | { 178 | return true 179 | } 180 | return false 181 | } 182 | 183 | override func tableView( _ tableView : UITableView, commit editingStyle : UITableViewCell.EditingStyle, forRowAt indexPath : IndexPath ) 184 | { 185 | if editingStyle == .delete 186 | { 187 | tableView.beginUpdates() 188 | if let rows = rows 189 | { 190 | self.rows?.remove( at : indexPath.row - 1 ) 191 | tableView.deleteRows( at : [ indexPath ], with : .automatic ) 192 | deleteRow( row : rows[ indexPath.row - 1 ], id : rows[ indexPath.row - 1 ].id ) 193 | } 194 | else 195 | { 196 | if let id = filteredRows?[ indexPath.row ][ "ROWID" ] as? Int64 197 | { 198 | filteredRows?.remove( at : indexPath.row - 1 ) 199 | tableView.deleteRows( at : [ indexPath ], with : .automatic ) 200 | deleteRow( row : nil, id : id ) 201 | } 202 | } 203 | tableView.endUpdates() 204 | } 205 | } 206 | 207 | // MARK: - Fetch data from Catalyst sdk 208 | 209 | func getTable() 210 | { 211 | ZCatalystApp.shared.getDataStoreInstance().getTable( name : tableName ) { ( result ) in 212 | switch result 213 | { 214 | case .success( let table ) : 215 | if self.tableName == "Tasks" 216 | { 217 | self.dataBuilder.setTask( table : table ) 218 | } 219 | else 220 | { 221 | self.dataBuilder.setProject( table : table ) 222 | } 223 | self.getRows( from : table ) 224 | case .error( let error ) : 225 | print( "Error occurred >>> \( error )" ) 226 | } 227 | } 228 | } 229 | 230 | func getRows( from table : ZCatalystTable ) 231 | { 232 | table.getRows { ( rowResult ) in 233 | switch rowResult 234 | { 235 | case .success( let rows ) : 236 | self.rows = rows 237 | DispatchQueue.main.async { 238 | self.tableView.reloadData() 239 | } 240 | if self.tableName == "Tasks" 241 | { 242 | self.dataBuilder.setTasks( rows ) 243 | } 244 | else 245 | { 246 | self.dataBuilder.setProjects( rows ) 247 | } 248 | case .error( let error ) : 249 | print( "Error occurred >>> \( error )" ) 250 | } 251 | } 252 | } 253 | 254 | func getRowsFromSearch() 255 | { 256 | if let searchOptions = searchOptions 257 | { 258 | ZCatalystApp.shared.search( searchOptions : searchOptions ) { ( result ) in 259 | switch result 260 | { 261 | case .success( let result ) : 262 | if let tasks = result[ "Tasks" ] as? [ [ String : Any ] ] 263 | { 264 | self.filteredRows = tasks 265 | } 266 | else if let projects = result[ "Projects" ] as? [ [ String : Any ] ] 267 | { 268 | self.filteredRows = projects 269 | } 270 | DispatchQueue.main.async { 271 | self.tableView.reloadData() 272 | } 273 | case .error( let error ) : 274 | print( "Error occurred >>> \( error )" ) 275 | } 276 | } 277 | } 278 | } 279 | 280 | func deleteRow( row : ZCatalystRow?, id : Int64 ) 281 | { 282 | if let row = row 283 | { 284 | row.delete { ( error ) in 285 | if let error = error 286 | { 287 | print( "Error occurred >>> \( error )" ) 288 | } 289 | } 290 | } 291 | else 292 | { 293 | if tableName == "Tasks" 294 | { 295 | if let table = dataBuilder.getData().getTask() 296 | { 297 | getRow( with : id, from : table ) 298 | } 299 | else 300 | { 301 | ZCatalystApp.shared.getDataStoreInstance().getTable( name : tableName ) { ( result ) in 302 | switch result 303 | { 304 | case .success( let table ) : 305 | if self.tableName == "Tasks" 306 | { 307 | self.dataBuilder.setTask( table : table ) 308 | } 309 | else 310 | { 311 | self.dataBuilder.setProject( table : table ) 312 | } 313 | self.getRow( with : id, from : table ) 314 | case .error( let error ) : 315 | print( "Error occurred >>> \( error )" ) 316 | } 317 | } 318 | } 319 | } 320 | else 321 | { 322 | if let table = dataBuilder.getData().getProject() 323 | { 324 | getRow( with : id, from : table ) 325 | } 326 | else 327 | { 328 | ZCatalystApp.shared.getDataStoreInstance().getTable( name : tableName ) { ( result ) in 329 | switch result 330 | { 331 | case .success( let table ) : 332 | if self.tableName == "Tasks" 333 | { 334 | self.dataBuilder.setTask( table : table ) 335 | } 336 | else 337 | { 338 | self.dataBuilder.setProject( table : table ) 339 | } 340 | self.getRow( with : id, from : table ) 341 | case .error( let error ) : 342 | print( "Error occurred >>> \( error )" ) 343 | } 344 | } 345 | } 346 | } 347 | } 348 | } 349 | 350 | func getRow( with id : Int64, from table : ZCatalystTable ) 351 | { 352 | table.getRow( id : id ) { ( result ) in 353 | switch result 354 | { 355 | case .success( let row ) : 356 | self.delete( row : row ) 357 | case .error( let error ) : 358 | print( "Error occurred >>> \( error )" ) 359 | } 360 | } 361 | } 362 | 363 | func delete( row : ZCatalystRow ) 364 | { 365 | row.delete { ( error ) in 366 | if let error = error 367 | { 368 | print( "Error occurred >>> \( error )" ) 369 | } 370 | } 371 | } 372 | } 373 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/HomeController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeController.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 03/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ZCatalyst 11 | 12 | class HomeController : UITableViewController 13 | { 14 | static let cellIdentifier = "tableViewCell" 15 | var tasksFrom = [ "All Tasks", "Today", "High Priority" ] 16 | var dataBuilder = CatalystDataBuilder() 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | if !ZCatalystApp.shared.isUserSignedIn() 22 | { 23 | ZCatalystApp.shared.showLogin { ( error ) in 24 | if let error = error 25 | { 26 | print( "Error occurred in login. Error >> \( error )" ) 27 | } 28 | else 29 | { 30 | self.getProjects() 31 | } 32 | } 33 | } 34 | else 35 | { 36 | getProjects() 37 | } 38 | tableView.register( UITableViewCell.self, forCellReuseIdentifier : HomeController.cellIdentifier ) 39 | self.tableView.register( AddRowCell.self, forCellReuseIdentifier : AddRowCell.identifier ) 40 | tableView.tableFooterView = nil 41 | 42 | let logoutButton = UIBarButtonItem( title : "Logout", style : .plain, target : self, action : #selector( logout ) ) 43 | self.navigationItem.setRightBarButton( logoutButton, animated : true ) 44 | self.navigationItem.title = "Todo" 45 | } 46 | 47 | // MARK: - Table view data source 48 | 49 | override func numberOfSections( in tableView : UITableView ) -> Int 50 | { 51 | return 2 52 | } 53 | 54 | override func tableView( _ tableView : UITableView, numberOfRowsInSection section : Int ) -> Int 55 | { 56 | if section == 0 57 | { 58 | return tasksFrom.count 59 | } 60 | else 61 | { 62 | if let projects = dataBuilder.getData().getProjects() 63 | { 64 | return projects.count + 1 65 | } 66 | return 0 67 | } 68 | } 69 | 70 | override func tableView( _ tableView : UITableView, cellForRowAt indexPath : IndexPath ) -> UITableViewCell 71 | { 72 | let cell = tableView.dequeueReusableCell( withIdentifier : HomeController.cellIdentifier, for : indexPath ) 73 | if indexPath.section == 0 74 | { 75 | cell.textLabel?.text = tasksFrom[ indexPath.row ] 76 | } 77 | else 78 | { 79 | if indexPath.row == 0 80 | { 81 | let addRow = AddRowCell.dequeue( self.tableView, indexPath : indexPath, title : "+ Add a Project", tableName : "Projects", dataBuilder : dataBuilder, cellPadding : self.view.bounds.width * 0.01 ) 82 | return addRow 83 | } 84 | else 85 | { 86 | if let projects = dataBuilder.getData().getProjects() 87 | { 88 | cell.textLabel?.text = projects[ indexPath.row - 1 ][ "Title" ] 89 | } 90 | } 91 | } 92 | return cell 93 | } 94 | 95 | override func tableView( _ tableView : UITableView, titleForHeaderInSection section : Int ) -> String? 96 | { 97 | if section == 0 98 | { 99 | return "Tasks" 100 | } 101 | else 102 | { 103 | return "Projects" 104 | } 105 | } 106 | 107 | override func tableView( _ tableView : UITableView, didSelectRowAt indexPath : IndexPath ) 108 | { 109 | let controller = ListViewController( tableName : "Tasks", searchOptions : constructSearchOption( indexPath : indexPath ), dataBuilder : dataBuilder ) 110 | self.navigationController?.pushViewController( controller, animated : true ) 111 | } 112 | 113 | // MARK: - Fetch data from Catalyst sdk 114 | 115 | func getProjects() 116 | { 117 | ZCatalystApp.shared.getDataStoreInstance().getTable( name : "Projects") { ( result ) in 118 | switch result 119 | { 120 | case .success( let table ) : 121 | self.dataBuilder.setProject( table : table ) 122 | table.getRows { ( rowsResult ) in 123 | switch rowsResult 124 | { 125 | case .success( let rows ) : 126 | self.dataBuilder.setProjects( rows ) 127 | DispatchQueue.main.async { 128 | self.tableView.reloadSections( [ 1 ], with : .none ) 129 | } 130 | case .error( let error ) : 131 | print( "Error occurred >>> \( error )" ) 132 | } 133 | } 134 | case .error( let error ) : 135 | print( "Error occurred >>> \( error )" ) 136 | } 137 | } 138 | } 139 | 140 | //MARK: - Utility functions 141 | 142 | func constructSearchOption( indexPath : IndexPath ) -> ZCatalystSearchOptions? 143 | { 144 | if indexPath.section == 0 145 | { 146 | if tasksFrom[ indexPath.row ] == "Today" 147 | { 148 | let dateFormatter = DateFormatter() 149 | dateFormatter.dateFormat = "yyyy-MM-dd" 150 | var searchColumns = ZCatalystSearchOptions.TableColumns( tableName : "Tasks" ) 151 | searchColumns.add( column : "DueDate" ) 152 | var searchOptions = ZCatalystSearchOptions( searchText : dateFormatter.string( from : Date() ), searchColumns: [ searchColumns ] ) 153 | var displayColumns = ZCatalystSearchOptions.TableColumns( tableName : "Tasks" ) 154 | displayColumns.add( column : "Title" ) 155 | searchOptions.add( displayColumns : displayColumns ) 156 | return searchOptions 157 | } 158 | else if tasksFrom[ indexPath.row ] == "Next 7 days" 159 | { 160 | var searchColumns = ZCatalystSearchOptions.TableColumns( tableName : "Tasks" ) 161 | searchColumns.add( column : "DueDate" ) 162 | var searchOptions = ZCatalystSearchOptions( searchText : "2020-09-07 20:00:00", searchColumns: [ searchColumns ] ) 163 | var displayColumns = ZCatalystSearchOptions.TableColumns( tableName : "Tasks" ) 164 | displayColumns.add( column : "Title" ) 165 | searchOptions.add( displayColumns : displayColumns ) 166 | return searchOptions 167 | } 168 | else if tasksFrom[ indexPath.row ] == "High Priority" 169 | { 170 | var searchColumns = ZCatalystSearchOptions.TableColumns( tableName : "Tasks" ) 171 | searchColumns.add( column : "Priority" ) 172 | var searchOptions = ZCatalystSearchOptions( searchText : "High", searchColumns: [ searchColumns ] ) 173 | var displayColumns = ZCatalystSearchOptions.TableColumns( tableName : "Tasks" ) 174 | displayColumns.add( column : "Title" ) 175 | searchOptions.add( displayColumns : displayColumns ) 176 | return searchOptions 177 | } 178 | return nil 179 | } 180 | else 181 | { 182 | if let projects = dataBuilder.getData().getProjects(), let projectId : String = projects[ indexPath.row - 1 ].getValue( forKey : "ROWID" ) 183 | { 184 | var searchColumns = ZCatalystSearchOptions.TableColumns( tableName : "Tasks" ) 185 | searchColumns.add( column : "ProjectId" ) 186 | var searchOptions = ZCatalystSearchOptions( searchText : projectId, searchColumns: [ searchColumns ] ) 187 | var displayColumns = ZCatalystSearchOptions.TableColumns( tableName : "Tasks" ) 188 | displayColumns.add( column : "Title" ) 189 | searchOptions.add( displayColumns : displayColumns ) 190 | return searchOptions 191 | } 192 | return nil 193 | } 194 | } 195 | 196 | @objc func logout() 197 | { 198 | ZCatalystApp.shared.logout { ( error ) in 199 | if let error = error 200 | { 201 | print( "Error occurred while logging out >>> \( error )" ) 202 | } 203 | else 204 | { 205 | print( "User logged out successfully..." ) 206 | self.dataBuilder = CatalystDataBuilder() 207 | self.tableView.reloadData() 208 | ZCatalystApp.shared.showLogin { ( error ) in 209 | if let error = error 210 | { 211 | print( "Error occurred in login. Error >> \( error )" ) 212 | } 213 | else 214 | { 215 | self.getProjects() 216 | } 217 | } 218 | } 219 | } 220 | } 221 | } 222 | 223 | protocol Builder 224 | { 225 | func setProjects( _ projects : [ ZCatalystRow ] ) 226 | 227 | func setProject( table : ZCatalystTable ) 228 | 229 | func setTasks( _ tasks : [ ZCatalystRow ] ) 230 | 231 | func setTask( table : ZCatalystTable ) 232 | 233 | func setColumns( _ columns : [ ZCatalystColumn ], for table : ZCatalystTable ) 234 | 235 | func addFilePath( for id : Int64, path : URL ) 236 | } 237 | 238 | class CatalystDataBuilder : Builder 239 | { 240 | private var data = CatalystData() 241 | 242 | func getData() -> CatalystData 243 | { 244 | return data 245 | } 246 | 247 | func setProjects( _ projects : [ ZCatalystRow ] ) 248 | { 249 | data.setProjects( projects ) 250 | } 251 | 252 | func setProject( table : ZCatalystTable ) 253 | { 254 | data.setProject( table : table ) 255 | } 256 | 257 | func setTasks( _ tasks : [ ZCatalystRow ] ) 258 | { 259 | data.setTasks( tasks ) 260 | } 261 | 262 | func setTask( table : ZCatalystTable ) 263 | { 264 | data.setTask( table : table ) 265 | } 266 | 267 | func setColumns( _ columns : [ ZCatalystColumn ], for table : ZCatalystTable ) 268 | { 269 | data.setColumns( columns, for : table ) 270 | } 271 | 272 | func setFolder( folder : ZCatalystFolder ) 273 | { 274 | data.setFolder( folder : folder ) 275 | } 276 | 277 | func addFile( _ file : ZCatalystFile ) 278 | { 279 | data.addFile( file ) 280 | } 281 | 282 | func addFilePath( for id : Int64, path : URL ) 283 | { 284 | data.addFilePath( for : id, path : path ) 285 | } 286 | } 287 | 288 | struct CatalystData 289 | { 290 | private var projects : [ ZCatalystRow ]? 291 | private var tasks : [ ZCatalystRow ]? 292 | private var project : ZCatalystTable? 293 | private var task : ZCatalystTable? 294 | private var projectsColumn : [ ZCatalystColumn ]? 295 | private var tasksColumn : [ ZCatalystColumn ]? 296 | private var folder : ZCatalystFolder? 297 | private var files : [ ZCatalystFile ]? 298 | private var filePaths : [ Int64 : URL ]? 299 | 300 | mutating func setProjects( _ projects : [ ZCatalystRow ] ) 301 | { 302 | self.projects = projects 303 | } 304 | 305 | mutating func setProject( table : ZCatalystTable ) 306 | { 307 | self.project = table 308 | } 309 | 310 | mutating func setTasks( _ tasks : [ ZCatalystRow ] ) 311 | { 312 | self.tasks = tasks 313 | } 314 | 315 | mutating func setTask( table : ZCatalystTable ) 316 | { 317 | self.task = table 318 | } 319 | 320 | mutating func setColumns( _ columns : [ ZCatalystColumn ], for table : ZCatalystTable ) 321 | { 322 | if table.name == "Tasks" 323 | { 324 | self.task = table 325 | self.tasksColumn = columns 326 | } 327 | else if table.name == "Projects" 328 | { 329 | self.project = table 330 | self.projectsColumn = columns 331 | } 332 | } 333 | 334 | mutating func setFolder( folder : ZCatalystFolder ) 335 | { 336 | self.folder = folder 337 | } 338 | 339 | mutating func addFile( _ file : ZCatalystFile ) 340 | { 341 | if self.files == nil 342 | { 343 | self.files = [ ZCatalystFile ]() 344 | } 345 | self.files?.append( file ) 346 | } 347 | 348 | mutating func addFilePath( for id : Int64, path : URL ) 349 | { 350 | if self.filePaths == nil 351 | { 352 | self.filePaths = [ Int64 : URL ]() 353 | } 354 | self.filePaths?.updateValue( path, forKey : id ) 355 | } 356 | 357 | func getProject() -> ZCatalystTable? 358 | { 359 | return project 360 | } 361 | 362 | func getTask() -> ZCatalystTable? 363 | { 364 | return task 365 | } 366 | 367 | func getProjects() -> [ ZCatalystRow ]? 368 | { 369 | return projects 370 | } 371 | 372 | func getTasks() -> [ ZCatalystRow ]? 373 | { 374 | return tasks 375 | } 376 | 377 | func getProjectColumns() -> [ ZCatalystColumn ]? 378 | { 379 | return projectsColumn 380 | } 381 | 382 | func getTaskColumns() -> [ ZCatalystColumn ]? 383 | { 384 | return tasksColumn 385 | } 386 | 387 | func getFolder() -> ZCatalystFolder? 388 | { 389 | return folder 390 | } 391 | 392 | func getFile( id : Int64 ) -> ZCatalystFile? 393 | { 394 | if let files = files 395 | { 396 | for file in files 397 | { 398 | if file.id == id 399 | { 400 | return file 401 | } 402 | } 403 | } 404 | return nil 405 | } 406 | 407 | func getFilePath( for id : Int64 ) -> URL? 408 | { 409 | return self.filePaths?[ id ] 410 | } 411 | } 412 | 413 | func getCurrentViewController() -> UIViewController? 414 | { 415 | let window = UIApplication.shared.windows.first { $0.isKeyWindow } 416 | if let rootController = window?.rootViewController 417 | { 418 | var currentController : UIViewController! = rootController 419 | while( currentController.presentedViewController != nil ) 420 | { 421 | currentController = currentController.presentedViewController 422 | } 423 | return currentController 424 | } 425 | return nil 426 | } 427 | 428 | 429 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/ButtonFieldCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonFieldCell.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 22/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ZCatalyst 11 | import MobileCoreServices 12 | 13 | class ButtonFieldCell : UITableViewCell 14 | { 15 | let background = UIView() 16 | let button = UIButton() 17 | let label = UILabel() 18 | var displayLabel = String() 19 | var cellPadding : CGFloat = 0 20 | var rowDataDelegate : RowDataDelegate? 21 | var dataBuilder : CatalystDataBuilder? 22 | var attachmentName : String? 23 | var isReadOnly : Bool = false 24 | static var identifier = "ButtonFieldCell" 25 | 26 | override func awakeFromNib() 27 | { 28 | super.awakeFromNib() 29 | // Initialization code 30 | } 31 | 32 | override func setSelected( _ selected : Bool, animated : Bool ) 33 | { 34 | super.setSelected( selected, animated : animated ) 35 | } 36 | 37 | static func dequeue( _ tableView : UITableView, for indexPath : IndexPath, displayLabel : String, attachmentName : String?, dataBuilder : CatalystDataBuilder, rowDataDelegate : RowDataDelegate?, isReadOnly : Bool, cellPadding : CGFloat ) -> ButtonFieldCell 38 | { 39 | let cell = tableView.dequeueReusableCell( withIdentifier : ButtonFieldCell.identifier, for : indexPath ) as? ButtonFieldCell ?? ButtonFieldCell() 40 | cell.rowDataDelegate = rowDataDelegate 41 | cell.attachmentName = attachmentName 42 | cell.displayLabel = displayLabel 43 | cell.cellPadding = cellPadding 44 | cell.dataBuilder = dataBuilder 45 | cell.isReadOnly = isReadOnly 46 | cell.constructCell() 47 | return cell 48 | } 49 | 50 | func setConstraints() 51 | { 52 | background.leadingAnchor.constraint( equalTo : contentView.leadingAnchor ).isActive = true 53 | background.widthAnchor.constraint( equalTo : contentView.widthAnchor, multiplier : 0.4 ).isActive = true 54 | background.topAnchor.constraint( equalTo : contentView.topAnchor ).isActive = true 55 | background.bottomAnchor.constraint( equalTo : contentView.bottomAnchor ).isActive = true 56 | 57 | label.leadingAnchor.constraint( equalTo : contentView.leadingAnchor, constant : cellPadding ).isActive = true 58 | label.trailingAnchor.constraint( equalTo : background.trailingAnchor, constant : -cellPadding ).isActive = true 59 | label.centerYAnchor.constraint( equalTo : contentView.centerYAnchor ).isActive = true 60 | 61 | button.trailingAnchor.constraint( equalTo : self.contentView.trailingAnchor, constant : -cellPadding ).isActive = true 62 | button.leadingAnchor.constraint( equalTo : background.trailingAnchor, constant : cellPadding ).isActive = true 63 | button.centerYAnchor.constraint( equalTo : self.contentView.centerYAnchor ).isActive = true 64 | } 65 | 66 | func constructCell() 67 | { 68 | for subview in self.contentView.subviews 69 | { 70 | subview.removeFromSuperview() 71 | } 72 | for subview in background.subviews 73 | { 74 | subview.removeFromSuperview() 75 | } 76 | 77 | if #available( iOS 13.0, * ) 78 | { 79 | background.backgroundColor = .secondarySystemBackground 80 | } 81 | else 82 | { 83 | background.backgroundColor = UIColor( red : 0.98, green : 0.98, blue : 0.98, alpha : 1.0 ) 84 | } 85 | background.translatesAutoresizingMaskIntoConstraints = false 86 | self.contentView.addSubview( background ) 87 | 88 | label.translatesAutoresizingMaskIntoConstraints = false 89 | label.text = displayLabel 90 | label.font = UIFont.systemFont( ofSize : 14 ) 91 | label.textColor = .systemGray 92 | label.textAlignment = .right 93 | background.addSubview( label ) 94 | 95 | button.translatesAutoresizingMaskIntoConstraints = false 96 | self.contentView.addSubview( button ) 97 | if let name = rowDataDelegate?.getAttachmentName() 98 | { 99 | button.setTitle( name, for : .normal ) 100 | } 101 | else if let attachmentName = attachmentName 102 | { 103 | button.setTitle( attachmentName, for : .normal ) 104 | } 105 | else if let row = rowDataDelegate?.getRow(), row.id == 0 106 | { 107 | button.setTitle( "+ Add an Attachment", for : .normal ) 108 | } 109 | button.setTitleColor( .systemBlue, for : .normal ) 110 | button.addTarget( self, action : #selector( navigate ), for: .touchUpInside ) 111 | 112 | setConstraints() 113 | } 114 | 115 | @objc func navigate() 116 | { 117 | let open = UIAlertAction( title : "Open Attachment", style : .default ) { ( _ ) in 118 | if let url = self.rowDataDelegate?.getAttachmentURL() 119 | { 120 | self.endEditing( true ) 121 | let documentInteractionController = UIDocumentInteractionController( url : url ) 122 | documentInteractionController.delegate = self 123 | documentInteractionController.presentPreview( animated : true ) 124 | } 125 | else if let _ = self.rowDataDelegate?.getAttachmentName() 126 | { 127 | let attachmentId : String? = self.rowDataDelegate?.getRow()?.getValue( forKey : "Attachment" ) 128 | if let attachmentId = attachmentId, let id = Int64( attachmentId ) 129 | { 130 | if let folder = self.dataBuilder?.getData().getFolder() 131 | { 132 | if let file = self.dataBuilder?.getData().getFile( id : id ) 133 | { 134 | if let url = self.dataBuilder?.getData().getFilePath( for : id ) 135 | { 136 | self.endEditing( true ) 137 | let documentInteractionController = UIDocumentInteractionController( url : url ) 138 | documentInteractionController.delegate = self 139 | documentInteractionController.presentPreview( animated : true ) 140 | } 141 | else 142 | { 143 | self.downloadFile( file ) 144 | } 145 | } 146 | else 147 | { 148 | self.getFile( id : id, folder : folder ) 149 | } 150 | } 151 | else 152 | { 153 | self.getFolder( fileId : id ) 154 | } 155 | } 156 | } 157 | } 158 | 159 | let takePhoto = UIAlertAction( title : "Take photo", style : .default ) { ( _ ) in 160 | self.addImagePickerController( sourceType : .camera ) 161 | } 162 | 163 | let addPhotoFromLibrary = UIAlertAction( title : "Add photo from library", style : .default) { ( _ ) in 164 | self.addImagePickerController( sourceType : .photoLibrary ) 165 | } 166 | 167 | self.endEditing( true ) 168 | let addFiles = UIAlertAction( title : "Add Files", style : .default) { ( _ ) in 169 | let documentPickerViewController = UIDocumentPickerViewController( documentTypes : [ kUTTypeFolder as String, kUTTypePDF as String, kUTTypeGIF as String, kUTTypeMP3 as String, kUTTypePNG as String, kUTTypeJPEG as String, kUTTypeMPEG as String, kUTTypeText as String, kUTTypeRTFD as String, kUTTypeAudio as String, kUTTypeImage as String, kUTTypeMovie as String, kUTTypeVideo as String, kUTTypeMPEG4 as String ], in : .import ) 170 | documentPickerViewController.allowsMultipleSelection = false 171 | documentPickerViewController.delegate = self 172 | ( getCurrentViewController() as? UINavigationController )?.present( documentPickerViewController, animated : true, completion : nil ) 173 | } 174 | 175 | let cancel = UIAlertAction( title : "Cancel", style : .cancel) { ( _ ) in 176 | } 177 | 178 | let remove = UIAlertAction( title : "Remove Photo", style : .destructive) { ( _ ) in 179 | self.rowDataDelegate?.setAttachmentURL( nil ) 180 | self.rowDataDelegate?.setAttachmentName( nil ) 181 | self.rowDataDelegate?.setRowData( for : "Attachment", value : nil ) 182 | } 183 | 184 | var alertActions = [ UIAlertAction ]() 185 | if rowDataDelegate?.getAttachmentURL() == nil && rowDataDelegate?.getAttachmentName() == nil 186 | { 187 | alertActions = [ takePhoto, addPhotoFromLibrary, addFiles, cancel ] 188 | } 189 | else 190 | { 191 | if isReadOnly 192 | { 193 | alertActions = [ open, takePhoto, addPhotoFromLibrary, addFiles, cancel ] 194 | } 195 | else 196 | { 197 | alertActions = [ open, takePhoto, addPhotoFromLibrary, addFiles, cancel, remove ] 198 | } 199 | } 200 | 201 | let alert : UIAlertController = getAlertController( title : nil, message : nil, preferredStyle : .actionSheet, with : alertActions ) 202 | 203 | self.endEditing( true ) 204 | getCurrentViewController()?.present( alert, animated : true, completion : nil ) 205 | } 206 | 207 | func getAlertController( title : String?, message : String?, preferredStyle : UIAlertController.Style, with actions : [ UIAlertAction ]? ) -> UIAlertController 208 | { 209 | let alert = UIAlertController( title : title, message : message, preferredStyle : preferredStyle ) 210 | 211 | if let actions = actions 212 | { 213 | for action in actions 214 | { 215 | alert.addAction( action ) 216 | } 217 | } 218 | return alert 219 | } 220 | 221 | func addImagePickerController( sourceType : UIImagePickerController.SourceType ) 222 | { 223 | let imagePicker = UIImagePickerController() 224 | if UIImagePickerController.isSourceTypeAvailable( sourceType ) 225 | { 226 | imagePicker.sourceType = sourceType 227 | imagePicker.delegate = self 228 | self.endEditing( true ) 229 | getCurrentViewController()?.present( imagePicker, animated : true, completion : nil ) 230 | } 231 | else 232 | { 233 | let okButton = UIAlertAction( title : "OK", style : .cancel ) { ( _ ) in 234 | } 235 | let alert : UIAlertController = getAlertController( title : "Permission denied", message : nil, preferredStyle : .alert, with : [ okButton ] ) 236 | 237 | self.endEditing( true ) 238 | getCurrentViewController()?.present( alert, animated : true, completion : nil ) 239 | } 240 | } 241 | 242 | func getFolder( fileId : Int64 ) 243 | { 244 | ZCatalystApp.shared.getFileStoreInstance().getFolder( id : 2823000000006561) { ( result ) in 245 | switch result 246 | { 247 | case .success( let folder ) : 248 | self.getFile( id : fileId, folder : folder ) 249 | self.dataBuilder?.setFolder( folder : folder ) 250 | case .error( let error ) : 251 | print( "Error occurred >>> \( error )" ) 252 | } 253 | } 254 | } 255 | 256 | func getFile( id : Int64, folder : ZCatalystFolder ) 257 | { 258 | folder.getFile( fileId : id) { ( result ) in 259 | switch result 260 | { 261 | case .success( let file ) : 262 | self.downloadFile( file ) 263 | self.dataBuilder?.addFile( file ) 264 | case .error( let error ) : 265 | print( "Error occurred >>> \( error )" ) 266 | } 267 | } 268 | } 269 | 270 | func downloadFile( _ file : ZCatalystFile ) 271 | { 272 | file.download { ( result ) in 273 | switch result 274 | { 275 | case .success( let fileResult ) : 276 | self.dataBuilder?.addFilePath( for : file.id, path : fileResult.1 ) 277 | do 278 | { 279 | let downloadedData = try Data( contentsOf : fileResult.1 ) 280 | DispatchQueue.main.async( execute : { 281 | print("transfer completion OK!") 282 | let documentDirectoryPath = NSSearchPathForDirectoriesInDomains( .documentDirectory, .userDomainMask, true ).first! as NSString 283 | let destinationPath = documentDirectoryPath.appendingPathComponent( file.name ) 284 | let fileURL = URL( fileURLWithPath : destinationPath ) 285 | FileManager.default.createFile( atPath : fileURL.path, contents : downloadedData, attributes : nil ) 286 | if FileManager.default.fileExists( atPath : fileURL.path ) 287 | { 288 | self.endEditing( true ) 289 | self.dataBuilder?.addFilePath( for : file.id, path : fileURL ) 290 | print( "pdfFileURL present!" ) // Confirm that the file is here! 291 | let documentInteractionController = UIDocumentInteractionController( url : fileURL ) 292 | documentInteractionController.delegate = self 293 | documentInteractionController.presentPreview( animated : true ) 294 | } 295 | } ) 296 | } 297 | catch 298 | { 299 | print( error ) 300 | } 301 | case .error( let error ) : 302 | print( "Error occurred >>> \( error )" ) 303 | } 304 | } 305 | } 306 | } 307 | 308 | extension ButtonFieldCell : UIDocumentPickerDelegate 309 | { 310 | func documentPicker( _ controller : UIDocumentPickerViewController, didPickDocumentsAt urls : [ URL ] ) 311 | { 312 | if let url = urls.first 313 | { 314 | self.rowDataDelegate?.setAttachmentURL( url ) 315 | } 316 | } 317 | } 318 | 319 | extension ButtonFieldCell : UIDocumentInteractionControllerDelegate 320 | { 321 | func documentInteractionControllerViewControllerForPreview( _ controller : UIDocumentInteractionController ) -> UIViewController 322 | { 323 | if let controller = getCurrentViewController() 324 | { 325 | return controller 326 | } 327 | return UIViewController() 328 | } 329 | } 330 | 331 | extension ButtonFieldCell : UIImagePickerControllerDelegate, UINavigationControllerDelegate 332 | { 333 | func imagePickerController( _ picker : UIImagePickerController, didFinishPickingMediaWithInfo info : [ UIImagePickerController.InfoKey : Any ] ) 334 | { 335 | if let url = info[ UIImagePickerController.InfoKey.imageURL ] as? URL 336 | { 337 | self.rowDataDelegate?.setAttachmentURL( url ) 338 | } 339 | } 340 | 341 | func imagePickerControllerDidCancel( _ picker : UIImagePickerController ) 342 | { 343 | picker.dismiss( animated : true, completion : nil ) 344 | } 345 | } 346 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/TextFieldCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextFieldCell.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 14/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ZCatalyst 11 | 12 | class TextFieldCell : UITableViewCell 13 | { 14 | let background = UIView() 15 | let textField = UITextField() 16 | let label = UILabel() 17 | var column : ZCatalystColumn? 18 | var value : String? 19 | var cellPadding : CGFloat = 0 20 | var rowDataDelegate : RowDataDelegate? 21 | var dataBuilder : CatalystDataBuilder? 22 | var pickerValues = [ String ]() 23 | var indexPath : IndexPath? 24 | static var identifier = "TextFieldCell" 25 | 26 | override func awakeFromNib() 27 | { 28 | super.awakeFromNib() 29 | // Initialization code 30 | } 31 | 32 | override func setSelected( _ selected : Bool, animated : Bool ) 33 | { 34 | super.setSelected( selected, animated : animated ) 35 | } 36 | 37 | static func dequeue( _ tableView : UITableView, for indexPath : IndexPath, column : ZCatalystColumn, value : String?, rowDataDelegate : RowDataDelegate, dataBuilder : CatalystDataBuilder, cellPadding : CGFloat ) -> TextFieldCell 38 | { 39 | let cell = tableView.dequeueReusableCell( withIdentifier : TextFieldCell.identifier, for : indexPath ) as? TextFieldCell ?? TextFieldCell() 40 | cell.column = column 41 | cell.value = value 42 | cell.rowDataDelegate = rowDataDelegate 43 | cell.dataBuilder = dataBuilder 44 | cell.indexPath = indexPath 45 | cell.cellPadding = cellPadding 46 | cell.constructCell() 47 | return cell 48 | } 49 | 50 | func setConstraints() 51 | { 52 | background.leadingAnchor.constraint( equalTo : contentView.leadingAnchor ).isActive = true 53 | background.widthAnchor.constraint( equalTo : contentView.widthAnchor, multiplier : 0.4 ).isActive = true 54 | background.topAnchor.constraint( equalTo : contentView.topAnchor ).isActive = true 55 | background.bottomAnchor.constraint( equalTo : contentView.bottomAnchor ).isActive = true 56 | 57 | label.leadingAnchor.constraint( equalTo : contentView.leadingAnchor, constant : cellPadding ).isActive = true 58 | label.trailingAnchor.constraint( equalTo : background.trailingAnchor, constant : -cellPadding ).isActive = true 59 | label.centerYAnchor.constraint( equalTo : contentView.centerYAnchor ).isActive = true 60 | 61 | textField.trailingAnchor.constraint( equalTo : self.contentView.trailingAnchor, constant : -cellPadding ).isActive = true 62 | textField.leadingAnchor.constraint( equalTo : background.trailingAnchor, constant : cellPadding ).isActive = true 63 | textField.centerYAnchor.constraint( equalTo : self.contentView.centerYAnchor ).isActive = true 64 | 65 | if let rightView = textField.rightView, let imageView = rightView as? UIImageView 66 | { 67 | let height = self.contentView.bounds.height * 0.8 68 | textField.rightView?.widthAnchor.constraint( equalToConstant : height ).isActive = true 69 | 70 | imageView.topAnchor.constraint( equalTo : rightView.topAnchor ).isActive = true 71 | imageView.bottomAnchor.constraint( equalTo : rightView.bottomAnchor ).isActive = true 72 | imageView.trailingAnchor.constraint( equalTo : rightView.trailingAnchor ).isActive = true 73 | imageView.leadingAnchor.constraint( equalTo : rightView.leadingAnchor ).isActive = true 74 | } 75 | } 76 | 77 | func constructCell() 78 | { 79 | for subview in self.contentView.subviews 80 | { 81 | subview.removeFromSuperview() 82 | } 83 | for subview in background.subviews 84 | { 85 | subview.removeFromSuperview() 86 | } 87 | 88 | if #available( iOS 13.0, * ) 89 | { 90 | background.backgroundColor = .secondarySystemBackground 91 | } 92 | else 93 | { 94 | background.backgroundColor = UIColor( red : 0.98, green : 0.98, blue : 0.98, alpha : 1.0 ) 95 | } 96 | background.translatesAutoresizingMaskIntoConstraints = false 97 | self.contentView.addSubview( background ) 98 | 99 | if let column = column 100 | { 101 | label.translatesAutoresizingMaskIntoConstraints = false 102 | label.text = column.name 103 | label.font = UIFont.systemFont( ofSize : 14 ) 104 | if column.isMandatory == true 105 | { 106 | label.textColor = .systemRed 107 | } 108 | else 109 | { 110 | label.textColor = .systemGray 111 | } 112 | label.textAlignment = .right 113 | background.addSubview( label ) 114 | 115 | textField.translatesAutoresizingMaskIntoConstraints = false 116 | textField.isUserInteractionEnabled = true 117 | textField.delegate = self 118 | let value : String? = rowDataDelegate?.getRow()?[ column.name ] 119 | textField.text = value 120 | textField.font = UIFont.systemFont( ofSize : 14 ) 121 | textField.textAlignment = .left 122 | textField.rightView = nil 123 | textField.inputView = nil 124 | self.contentView.addSubview( textField ) 125 | customizeTextField() 126 | } 127 | 128 | setConstraints() 129 | } 130 | 131 | func customizeTextField() 132 | { 133 | if let column = column 134 | { 135 | switch column.dataType 136 | { 137 | case .text, .varchar : 138 | if column.name != "Priority" 139 | { 140 | textField.keyboardType = .default 141 | } 142 | else 143 | { 144 | pickerValues = [ "Low", "Medium", "High" ] 145 | let arrow = UIImageView( image : UIImage( named : "DownArrow" ) ) 146 | arrow.contentMode = .scaleAspectFit 147 | arrow.translatesAutoresizingMaskIntoConstraints = false 148 | 149 | textField.rightView = arrow 150 | textField.rightViewMode = .always 151 | } 152 | 153 | case .date, .datetime : 154 | let arrow = UIImageView( image : UIImage( named : "DownArrow" ) ) 155 | arrow.contentMode = .scaleAspectFit 156 | arrow.translatesAutoresizingMaskIntoConstraints = false 157 | 158 | textField.rightView = arrow 159 | textField.rightViewMode = .always 160 | 161 | case .int, .bigint : 162 | textField.keyboardType = .numberPad 163 | 164 | case .double : 165 | textField.keyboardType = .decimalPad 166 | 167 | case .foreignKey : 168 | let arrow = UIImageView( image : UIImage( named : "RightArrow" ) ) 169 | arrow.contentMode = .scaleAspectFit 170 | arrow.translatesAutoresizingMaskIntoConstraints = false 171 | 172 | textField.rightView = arrow 173 | textField.rightViewMode = .always 174 | 175 | default : 176 | print( "Type not supported" ) 177 | } 178 | } 179 | } 180 | } 181 | 182 | extension TextFieldCell : UITextFieldDelegate 183 | { 184 | func getDatePickerView() -> UIDatePicker 185 | { 186 | let datePickerView = UIDatePicker() 187 | if column?.dataType == ZCatalystColumn.DataType.date 188 | { 189 | datePickerView.datePickerMode = .date 190 | } 191 | else 192 | { 193 | datePickerView.datePickerMode = .dateAndTime 194 | } 195 | datePickerView.calendar = .autoupdatingCurrent 196 | if #available( iOS 13.0, * ) 197 | { 198 | datePickerView.backgroundColor = .systemBackground 199 | } 200 | else 201 | { 202 | datePickerView.backgroundColor = .white 203 | } 204 | datePickerView.translatesAutoresizingMaskIntoConstraints = false 205 | self.addSubview( datePickerView ) 206 | 207 | datePickerView.addTarget( self, action : #selector( handleDatePickerEvent( _ : ) ), for : .valueChanged ) 208 | 209 | datePickerView.leadingAnchor.constraint( equalTo : self.leadingAnchor ).isActive = true 210 | datePickerView.trailingAnchor.constraint( equalTo : self.trailingAnchor ).isActive = true 211 | datePickerView.bottomAnchor.constraint( equalTo : self.bottomAnchor ).isActive = true 212 | datePickerView.widthAnchor.constraint( equalTo : self.widthAnchor ).isActive = true 213 | datePickerView.autoresizingMask = .flexibleHeight 214 | 215 | return datePickerView 216 | } 217 | 218 | func getPickerView() -> UIPickerView 219 | { 220 | let pickerView = UIPickerView() 221 | 222 | pickerView.delegate = self 223 | pickerView.dataSource = self 224 | if #available( iOS 13.0, * ) 225 | { 226 | pickerView.backgroundColor = .systemBackground 227 | } 228 | else 229 | { 230 | pickerView.backgroundColor = .white 231 | } 232 | pickerView.translatesAutoresizingMaskIntoConstraints = true 233 | self.addSubview( pickerView ) 234 | 235 | pickerView.leadingAnchor.constraint( equalTo : self.leadingAnchor ).isActive = true 236 | pickerView.trailingAnchor.constraint( equalTo : self.trailingAnchor ).isActive = true 237 | pickerView.bottomAnchor.constraint( equalTo : self.bottomAnchor ).isActive = true 238 | pickerView.widthAnchor.constraint( equalTo : self.widthAnchor ).isActive = true 239 | pickerView.autoresizingMask = .flexibleHeight 240 | 241 | return pickerView 242 | } 243 | 244 | func getToolBar() -> UIToolbar 245 | { 246 | let toolBar = UIToolbar() 247 | toolBar.barStyle = .default 248 | if #available( iOS 13.0, * ) 249 | { 250 | toolBar.backgroundColor = .tertiarySystemGroupedBackground 251 | } 252 | else 253 | { 254 | toolBar.backgroundColor = .clear 255 | } 256 | toolBar.sizeToFit() 257 | 258 | let clearButton = UIBarButtonItem( title : "Clear", style : .plain, target : self, action : #selector( clear ) ) 259 | let spaceButton = UIBarButtonItem( barButtonSystemItem : .flexibleSpace, target : nil, action : nil ) 260 | let doneButton = UIBarButtonItem( title : "Done", style : .done, target : self, action : #selector( done ) ) 261 | toolBar.setItems( [ clearButton, spaceButton, doneButton ], animated : false ) 262 | toolBar.isUserInteractionEnabled = true 263 | 264 | return toolBar 265 | } 266 | 267 | @objc func clear( _ sender : UIDatePicker ) 268 | { 269 | if let column = column 270 | { 271 | self.textField.text = nil 272 | rowDataDelegate?.setRowData( for : column.name, value : nil ) 273 | } 274 | 275 | } 276 | 277 | @objc func done( _ sender : AnyObject ) 278 | { 279 | self.endEditing( true ) 280 | } 281 | 282 | @objc func handleDatePickerEvent( _ sender : UIDatePicker ) 283 | { 284 | if let column = column 285 | { 286 | if column.dataType == ZCatalystColumn.DataType.date 287 | { 288 | textField.text = sender.date.date 289 | rowDataDelegate?.setRowData( for : column.name, value : sender.date.iso8601 ) 290 | } 291 | else if column.dataType == ZCatalystColumn.DataType.datetime 292 | { 293 | textField.text = sender.date.dateTime 294 | rowDataDelegate?.setRowData( for : column.name, value : sender.date.iso8601WithTimeZone ) 295 | } 296 | else 297 | { 298 | print( "DateFormat did not match" ) 299 | } 300 | } 301 | } 302 | 303 | func textFieldDidBeginEditing( _ textField : UITextField ) 304 | { 305 | if let tableView = self.superview as? UITableView, let indexPath = indexPath 306 | { 307 | tableView.scrollToRow( at : indexPath, at : .middle, animated : true ) 308 | tableView.isScrollEnabled = false 309 | } 310 | if let column = column 311 | { 312 | if column.name == "Priority" 313 | { 314 | let pickerView = getPickerView() 315 | pickerView.removeFromSuperview() 316 | textField.inputView = pickerView 317 | if let text = textField.text, !text.isEmpty 318 | { 319 | for index in 0.. Int 408 | { 409 | return 1 410 | } 411 | 412 | func pickerView( _ pickerView : UIPickerView, numberOfRowsInComponent component : Int ) -> Int 413 | { 414 | return pickerValues.count 415 | } 416 | } 417 | 418 | extension TextFieldCell : UIPickerViewDelegate 419 | { 420 | func pickerView( _ pickerView : UIPickerView, titleForRow row : Int, forComponent component : Int ) -> String? 421 | { 422 | return pickerValues[ row ] 423 | } 424 | 425 | func pickerView( _ pickerView : UIPickerView, didSelectRow row : Int, inComponent component : Int ) 426 | { 427 | if let column = column 428 | { 429 | textField.text = pickerValues[ row ] 430 | rowDataDelegate?.setRowData( for : column.name, value : pickerValues[ row ] ) 431 | } 432 | } 433 | } 434 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App/CreateController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CreateController.swift 3 | // CatalystTestApp 4 | // 5 | // Created by Umashri R on 11/09/20. 6 | // Copyright © 2020 Umashri R. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ZCatalyst 11 | 12 | class CreateController : UITableViewController 13 | { 14 | let tableName : String 15 | let dataBuilder : CatalystDataBuilder 16 | var columns = [ ZCatalystColumn ]() 17 | { 18 | didSet 19 | { 20 | for index in 0.. Int 155 | { 156 | return 1 157 | } 158 | 159 | override func tableView( _ tableView : UITableView, numberOfRowsInSection section : Int ) -> Int 160 | { 161 | return columns.count 162 | } 163 | 164 | override func tableView( _ tableView : UITableView, cellForRowAt indexPath : IndexPath ) -> UITableViewCell 165 | { 166 | if columns[ indexPath.row ].dataType == .boolean 167 | { 168 | let cell = BooleanField.dequeue( self.tableView, for : indexPath, displayLabel : columns[ indexPath.row ].name, value : nil, rowDataDelegate : self, cellPadding : cellPadding ) 169 | return cell 170 | } 171 | else if columns[ indexPath.row ].name == "Attachment" 172 | { 173 | let id : String? = row?.getValue( forKey : "Attachment" ) 174 | if let id = id, let attachmentId = Int64( id ) 175 | { 176 | if let file = dataBuilder.getData().getFile( id : attachmentId ) 177 | { 178 | self.setAttachmentName( file.name ) 179 | } 180 | else 181 | { 182 | if let folder = dataBuilder.getData().getFolder() 183 | { 184 | folder.getFile( fileId : attachmentId) { ( result ) in 185 | switch result 186 | { 187 | case .success( let file ) : 188 | self.setAttachmentName( file.name ) 189 | self.dataBuilder.addFile( file ) 190 | DispatchQueue.main.async { 191 | self.tableView.reloadRows( at : [ indexPath ], with : .automatic ) 192 | } 193 | case .error( let error ) : 194 | print( "Error occurred >>> \( error )" ) 195 | } 196 | } 197 | } 198 | else 199 | { 200 | ZCatalystApp.shared.getFileStoreInstance().getFolder( id : 2823000000006561 ) { ( folderResult ) in 201 | switch folderResult 202 | { 203 | case .success( let folder ) : 204 | self.dataBuilder.setFolder( folder : folder ) 205 | folder.getFile( fileId : attachmentId) { ( result ) in 206 | switch result 207 | { 208 | case .success( let file ) : 209 | self.setAttachmentName( file.name ) 210 | self.dataBuilder.addFile( file ) 211 | DispatchQueue.main.async { 212 | self.tableView.reloadRows( at : [ indexPath ], with : .automatic ) 213 | } 214 | case .error( let error ) : 215 | print( "Error occurred >>> \( error )" ) 216 | } 217 | } 218 | case .error( let error ) : 219 | print( "Error occurred >>> \( error )" ) 220 | } 221 | } 222 | } 223 | } 224 | } 225 | let cell = ButtonFieldCell.dequeue( tableView, for : indexPath, displayLabel : columns[ indexPath.row ].name, attachmentName : nil, dataBuilder : dataBuilder, rowDataDelegate : self, isReadOnly : false, cellPadding : cellPadding ) 226 | return cell 227 | } 228 | else 229 | { 230 | let cell = TextFieldCell.dequeue( tableView, for : indexPath, column : columns[ indexPath.row ], value : nil, rowDataDelegate : self, dataBuilder : dataBuilder, cellPadding : cellPadding ) 231 | return cell 232 | } 233 | } 234 | 235 | func addTapGestureRecognizer( with action : Selector ) 236 | { 237 | let gesture = UITapGestureRecognizer( target : self, action : action ) 238 | gesture.cancelsTouchesInView = false 239 | self.tableView.addGestureRecognizer( gesture ) 240 | } 241 | 242 | @objc func done( _ sender : AnyObject ) 243 | { 244 | self.tableView.endEditing( true ) 245 | } 246 | 247 | @objc func save() 248 | { 249 | if let row = row 250 | { 251 | var isMandatoryFilled = true 252 | for column in columns 253 | { 254 | if column.isMandatory == true, row.getData()[ column.name ] == nil 255 | { 256 | isMandatoryFilled = false 257 | } 258 | } 259 | if isMandatoryFilled 260 | { 261 | if row.id != 0 262 | { 263 | row.update { ( result ) in 264 | switch result 265 | { 266 | case .success( let updatedRow ) : 267 | print( "Edit successful" ) 268 | if self.tableName == "Tasks" 269 | { 270 | if let rows = self.dataBuilder.getData().getTasks() 271 | { 272 | var rows = rows 273 | for index in 0..>> \( error )" ) 303 | } 304 | } 305 | } 306 | else 307 | { 308 | if let attachmentURL = attachmentURL 309 | { 310 | if let folder = dataBuilder.getData().getFolder() 311 | { 312 | folder.upload( filePath : attachmentURL) { ( fileResult ) in 313 | switch fileResult 314 | { 315 | case .success( let file ) : 316 | self.dataBuilder.addFile( file ) 317 | row.setColumnValue( columnName : "Attachment", value : file.id ) 318 | self.create( row : row ) 319 | case .error( let error ) : 320 | print( "Error occurred >>> \( error )" ) 321 | } 322 | } 323 | } 324 | else 325 | { 326 | ZCatalystApp.shared.getFileStoreInstance().getFolder( id : 2823000000006561 ) { ( folderResult ) in 327 | switch folderResult 328 | { 329 | case .success( let folder ) : 330 | self.dataBuilder.setFolder( folder : folder ) 331 | folder.upload( filePath : attachmentURL) { ( fileResult ) in 332 | switch fileResult 333 | { 334 | case .success( let file ) : 335 | self.dataBuilder.addFile( file ) 336 | row.setColumnValue( columnName : "Attachment", value : file.id ) 337 | self.create( row : row ) 338 | case .error( let error ) : 339 | print( "Error occurred >>> \( error )" ) 340 | } 341 | } 342 | case .error( let error ) : 343 | print( "Error occurred >>> \( error )" ) 344 | } 345 | } 346 | } 347 | } 348 | else 349 | { 350 | create( row : row ) 351 | } 352 | } 353 | } 354 | else 355 | { 356 | let okButton = UIAlertAction( title : "OK", style : .cancel) { ( _ ) in 357 | getCurrentViewController()?.dismiss(animated: true, completion: nil) 358 | } 359 | let alert = UIAlertController( title : "Error", message : "Mandatory not filled", preferredStyle : .alert ) 360 | alert.addAction( okButton ) 361 | getCurrentViewController()?.present( alert, animated : true, completion : { 362 | alert.view.superview?.isUserInteractionEnabled = true 363 | } ) 364 | } 365 | } 366 | } 367 | 368 | // MARK: - Fetch data from Catalyst sdk 369 | 370 | func getTable( tableName : String ) 371 | { 372 | ZCatalystApp.shared.getDataStoreInstance().getTable( name : tableName ) { ( result ) in 373 | switch result 374 | { 375 | case .success( let table ) : 376 | self.getColumns( from : table ) 377 | if tableName == "Tasks" 378 | { 379 | self.dataBuilder.setTask( table : table ) 380 | } 381 | else if tableName == "Projects" 382 | { 383 | self.dataBuilder.setProject( table : table ) 384 | } 385 | if self.row == nil 386 | { 387 | self.row = table.newRow() 388 | } 389 | case .error( let error ) : 390 | print( "Error occurred >>> \( error )" ) 391 | } 392 | } 393 | } 394 | 395 | func getColumns( from table : ZCatalystTable ) 396 | { 397 | table.getColumns { ( result ) in 398 | switch result 399 | { 400 | case .success( let columns ) : 401 | for column in columns 402 | { 403 | if column.category != 1 404 | { 405 | if column.name == "isCompleted" 406 | { 407 | if self.row?.id != 0 408 | { 409 | self.columns.append( column ) 410 | } 411 | } 412 | else 413 | { 414 | self.columns.append( column ) 415 | } 416 | } 417 | } 418 | self.dataBuilder.setColumns( columns, for : table ) 419 | DispatchQueue.main.async 420 | { 421 | self.tableView.reloadData() 422 | } 423 | case .error( let error ) : 424 | print( "Error occurred >>> \( error )" ) 425 | } 426 | } 427 | } 428 | 429 | func create( row : ZCatalystRow ) 430 | { 431 | row.create { ( result ) in 432 | switch result 433 | { 434 | case .success( let createdRow ) : 435 | print( "Create successful..." ) 436 | if self.tableName == "Tasks" 437 | { 438 | if let rows = self.dataBuilder.getData().getTasks() 439 | { 440 | var rows = rows 441 | rows.append( createdRow ) 442 | self.dataBuilder.setTasks( rows ) 443 | } 444 | } 445 | else 446 | { 447 | if let rows = self.dataBuilder.getData().getProjects() 448 | { 449 | var rows = rows 450 | rows.append( createdRow ) 451 | self.dataBuilder.setProjects( rows ) 452 | } 453 | } 454 | DispatchQueue.main.async { 455 | ( getCurrentViewController() as? UINavigationController )?.popViewController( animated : true ) 456 | } 457 | case .error( let error ) : 458 | print( "Error occurred >>> \( error )" ) 459 | } 460 | } 461 | } 462 | } 463 | 464 | extension CreateController : RowDataDelegate 465 | { 466 | func getRow() -> ZCatalystRow? 467 | { 468 | return self.row 469 | } 470 | 471 | func setRowData( for columnName : String, value : Any? ) 472 | { 473 | self.row?.setColumnValue( columnName : columnName, value : value ) 474 | } 475 | 476 | func getAttachmentURL() -> URL? 477 | { 478 | return attachmentURL 479 | } 480 | 481 | func setAttachmentURL( _ url : URL? ) 482 | { 483 | self.attachmentURL = url 484 | self.attachmentName = url?.lastPathComponent 485 | self.tableView.reloadRows( at : [ IndexPath( row : 6, section : 0 ) ], with : .automatic ) 486 | } 487 | 488 | func getAttachmentName() -> String? 489 | { 490 | return attachmentName 491 | } 492 | 493 | func setAttachmentName( _ name : String? ) 494 | { 495 | self.attachmentName = name 496 | } 497 | } 498 | 499 | protocol RowDataDelegate 500 | { 501 | func getRow() -> ZCatalystRow? 502 | func setRowData( for columnName : String, value : Any? ) 503 | func getAttachmentURL() -> URL? 504 | func setAttachmentURL( _ url : URL? ) 505 | func getAttachmentName() -> String? 506 | func setAttachmentName( _ name : String? ) 507 | } 508 | -------------------------------------------------------------------------------- /Catalyst-iOS-SDK-Sample-App.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B10E262524FF6C8100C032ED /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10E262424FF6C8100C032ED /* AppDelegate.swift */; }; 11 | B10E262E24FF6C8400C032ED /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B10E262D24FF6C8400C032ED /* Assets.xcassets */; }; 12 | B10E263124FF6C8400C032ED /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B10E262F24FF6C8400C032ED /* LaunchScreen.storyboard */; }; 13 | B10E26392500F3DF00C032ED /* HomeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10E26382500F3DF00C032ED /* HomeController.swift */; }; 14 | B10E266D25024D4100C032ED /* ListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10E266C25024D4000C032ED /* ListViewController.swift */; }; 15 | B124F887250B5AF50014028C /* AddRowCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B124F886250B5AF50014028C /* AddRowCell.swift */; }; 16 | B1505499269C92B700EBDA4B /* AppConfigurationDevelopment1.plist in Resources */ = {isa = PBXBuildFile; fileRef = B1505498269C92B700EBDA4B /* AppConfigurationDevelopment1.plist */; }; 17 | B1595504267CB97A00D0BD76 /* AppConfigurationDevelopment.plist in Resources */ = {isa = PBXBuildFile; fileRef = B1595503267CB97A00D0BD76 /* AppConfigurationDevelopment.plist */; }; 18 | B179EABD2507C3FA00AE0779 /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B179EABC2507C3FA00AE0779 /* DetailViewController.swift */; }; 19 | B179EABF2509257000AE0779 /* Field.swift in Sources */ = {isa = PBXBuildFile; fileRef = B179EABE2509257000AE0779 /* Field.swift */; }; 20 | B179EAC1250A5EB500AE0779 /* BooleanField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B179EAC0250A5EB500AE0779 /* BooleanField.swift */; }; 21 | B179EAC3250A73BC00AE0779 /* ForeignKeyField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B179EAC2250A73BC00AE0779 /* ForeignKeyField.swift */; }; 22 | B1EF6E78250B8A310023DCB5 /* CreateController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF6E77250B8A310023DCB5 /* CreateController.swift */; }; 23 | B1EF6E7A250F99530023DCB5 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF6E79250F99530023DCB5 /* TextFieldCell.swift */; }; 24 | B1F50C79251A3B94002F7385 /* ButtonFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1F50C78251A3B94002F7385 /* ButtonFieldCell.swift */; }; 25 | B1FD2CAB250FA87400CB36FC /* CommonUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FD2CAA250FA87400CB36FC /* CommonUtil.swift */; }; 26 | D9C7EA643CD13E9B5B5198A4 /* Pods_Catalyst_iOS_SDK_Sample_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA1725B9CDA7850839C89AAA /* Pods_Catalyst_iOS_SDK_Sample_App.framework */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 9099E6CD979B60F312E4B508 /* Pods-Catalyst-iOS-SDK-Sample-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Catalyst-iOS-SDK-Sample-App.release.xcconfig"; path = "Target Support Files/Pods-Catalyst-iOS-SDK-Sample-App/Pods-Catalyst-iOS-SDK-Sample-App.release.xcconfig"; sourceTree = ""; }; 31 | B10E262124FF6C8100C032ED /* Catalyst-iOS-SDK-Sample-App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Catalyst-iOS-SDK-Sample-App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | B10E262424FF6C8100C032ED /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33 | B10E262D24FF6C8400C032ED /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 34 | B10E263024FF6C8400C032ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 35 | B10E263224FF6C8400C032ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | B10E26382500F3DF00C032ED /* HomeController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeController.swift; sourceTree = ""; }; 37 | B10E266C25024D4000C032ED /* ListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListViewController.swift; sourceTree = ""; }; 38 | B124F886250B5AF50014028C /* AddRowCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRowCell.swift; sourceTree = ""; }; 39 | B1505498269C92B700EBDA4B /* AppConfigurationDevelopment1.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AppConfigurationDevelopment1.plist; sourceTree = ""; }; 40 | B1595503267CB97A00D0BD76 /* AppConfigurationDevelopment.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AppConfigurationDevelopment.plist; sourceTree = ""; }; 41 | B179EABC2507C3FA00AE0779 /* DetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; }; 42 | B179EABE2509257000AE0779 /* Field.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Field.swift; sourceTree = ""; }; 43 | B179EAC0250A5EB500AE0779 /* BooleanField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BooleanField.swift; sourceTree = ""; }; 44 | B179EAC2250A73BC00AE0779 /* ForeignKeyField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForeignKeyField.swift; sourceTree = ""; }; 45 | B1EF6E77250B8A310023DCB5 /* CreateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateController.swift; sourceTree = ""; }; 46 | B1EF6E79250F99530023DCB5 /* TextFieldCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldCell.swift; sourceTree = ""; }; 47 | B1F50C78251A3B94002F7385 /* ButtonFieldCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonFieldCell.swift; sourceTree = ""; }; 48 | B1FD2CAA250FA87400CB36FC /* CommonUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonUtil.swift; sourceTree = ""; }; 49 | BE956A02CEE1835D527848D0 /* Pods-Catalyst-iOS-SDK-Sample-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Catalyst-iOS-SDK-Sample-App.debug.xcconfig"; path = "Target Support Files/Pods-Catalyst-iOS-SDK-Sample-App/Pods-Catalyst-iOS-SDK-Sample-App.debug.xcconfig"; sourceTree = ""; }; 50 | DA1725B9CDA7850839C89AAA /* Pods_Catalyst_iOS_SDK_Sample_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Catalyst_iOS_SDK_Sample_App.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | E792B9D67914821F0EC71534 /* Pods-CatalystTestApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CatalystTestApp.debug.xcconfig"; path = "Target Support Files/Pods-CatalystTestApp/Pods-CatalystTestApp.debug.xcconfig"; sourceTree = ""; }; 52 | E82CCC7347F27A07A3F8E84D /* Pods-CatalystTestApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CatalystTestApp.release.xcconfig"; path = "Target Support Files/Pods-CatalystTestApp/Pods-CatalystTestApp.release.xcconfig"; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | B10E261E24FF6C8100C032ED /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | D9C7EA643CD13E9B5B5198A4 /* Pods_Catalyst_iOS_SDK_Sample_App.framework in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | B10E261824FF6C8100C032ED = { 68 | isa = PBXGroup; 69 | children = ( 70 | B10E262324FF6C8100C032ED /* Catalyst-iOS-SDK-Sample-App */, 71 | B10E262224FF6C8100C032ED /* Products */, 72 | BC731FAADB17785D70EE9004 /* Pods */, 73 | D88DB7E824CCBE8052A8125E /* Frameworks */, 74 | ); 75 | sourceTree = ""; 76 | }; 77 | B10E262224FF6C8100C032ED /* Products */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | B10E262124FF6C8100C032ED /* Catalyst-iOS-SDK-Sample-App.app */, 81 | ); 82 | name = Products; 83 | sourceTree = ""; 84 | }; 85 | B10E262324FF6C8100C032ED /* Catalyst-iOS-SDK-Sample-App */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | B1505498269C92B700EBDA4B /* AppConfigurationDevelopment1.plist */, 89 | B1EF6E77250B8A310023DCB5 /* CreateController.swift */, 90 | B1F50C78251A3B94002F7385 /* ButtonFieldCell.swift */, 91 | B10E262424FF6C8100C032ED /* AppDelegate.swift */, 92 | B10E26382500F3DF00C032ED /* HomeController.swift */, 93 | B10E266C25024D4000C032ED /* ListViewController.swift */, 94 | B1EF6E79250F99530023DCB5 /* TextFieldCell.swift */, 95 | B124F886250B5AF50014028C /* AddRowCell.swift */, 96 | B179EAC2250A73BC00AE0779 /* ForeignKeyField.swift */, 97 | B179EABE2509257000AE0779 /* Field.swift */, 98 | B1595503267CB97A00D0BD76 /* AppConfigurationDevelopment.plist */, 99 | B179EAC0250A5EB500AE0779 /* BooleanField.swift */, 100 | B179EABC2507C3FA00AE0779 /* DetailViewController.swift */, 101 | B1FD2CAA250FA87400CB36FC /* CommonUtil.swift */, 102 | B10E262D24FF6C8400C032ED /* Assets.xcassets */, 103 | B10E262F24FF6C8400C032ED /* LaunchScreen.storyboard */, 104 | B10E263224FF6C8400C032ED /* Info.plist */, 105 | ); 106 | path = "Catalyst-iOS-SDK-Sample-App"; 107 | sourceTree = ""; 108 | }; 109 | BC731FAADB17785D70EE9004 /* Pods */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | E792B9D67914821F0EC71534 /* Pods-CatalystTestApp.debug.xcconfig */, 113 | E82CCC7347F27A07A3F8E84D /* Pods-CatalystTestApp.release.xcconfig */, 114 | BE956A02CEE1835D527848D0 /* Pods-Catalyst-iOS-SDK-Sample-App.debug.xcconfig */, 115 | 9099E6CD979B60F312E4B508 /* Pods-Catalyst-iOS-SDK-Sample-App.release.xcconfig */, 116 | ); 117 | path = Pods; 118 | sourceTree = ""; 119 | }; 120 | D88DB7E824CCBE8052A8125E /* Frameworks */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | DA1725B9CDA7850839C89AAA /* Pods_Catalyst_iOS_SDK_Sample_App.framework */, 124 | ); 125 | name = Frameworks; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXNativeTarget section */ 131 | B10E262024FF6C8100C032ED /* Catalyst-iOS-SDK-Sample-App */ = { 132 | isa = PBXNativeTarget; 133 | buildConfigurationList = B10E263524FF6C8400C032ED /* Build configuration list for PBXNativeTarget "Catalyst-iOS-SDK-Sample-App" */; 134 | buildPhases = ( 135 | B01AB787D93A1A61A830D7A3 /* [CP] Check Pods Manifest.lock */, 136 | B10E261D24FF6C8100C032ED /* Sources */, 137 | B10E261E24FF6C8100C032ED /* Frameworks */, 138 | B10E261F24FF6C8100C032ED /* Resources */, 139 | D65CFDC2FFB10653DFB5CFA2 /* [CP] Embed Pods Frameworks */, 140 | ); 141 | buildRules = ( 142 | ); 143 | dependencies = ( 144 | ); 145 | name = "Catalyst-iOS-SDK-Sample-App"; 146 | productName = CatalystTestApp; 147 | productReference = B10E262124FF6C8100C032ED /* Catalyst-iOS-SDK-Sample-App.app */; 148 | productType = "com.apple.product-type.application"; 149 | }; 150 | /* End PBXNativeTarget section */ 151 | 152 | /* Begin PBXProject section */ 153 | B10E261924FF6C8100C032ED /* Project object */ = { 154 | isa = PBXProject; 155 | attributes = { 156 | LastSwiftUpdateCheck = 1160; 157 | LastUpgradeCheck = 1160; 158 | ORGANIZATIONNAME = "Umashri R"; 159 | TargetAttributes = { 160 | B10E262024FF6C8100C032ED = { 161 | CreatedOnToolsVersion = 11.6; 162 | }; 163 | }; 164 | }; 165 | buildConfigurationList = B10E261C24FF6C8100C032ED /* Build configuration list for PBXProject "Catalyst-iOS-SDK-Sample-App" */; 166 | compatibilityVersion = "Xcode 9.3"; 167 | developmentRegion = en; 168 | hasScannedForEncodings = 0; 169 | knownRegions = ( 170 | en, 171 | Base, 172 | ); 173 | mainGroup = B10E261824FF6C8100C032ED; 174 | productRefGroup = B10E262224FF6C8100C032ED /* Products */; 175 | projectDirPath = ""; 176 | projectRoot = ""; 177 | targets = ( 178 | B10E262024FF6C8100C032ED /* Catalyst-iOS-SDK-Sample-App */, 179 | ); 180 | }; 181 | /* End PBXProject section */ 182 | 183 | /* Begin PBXResourcesBuildPhase section */ 184 | B10E261F24FF6C8100C032ED /* Resources */ = { 185 | isa = PBXResourcesBuildPhase; 186 | buildActionMask = 2147483647; 187 | files = ( 188 | B10E263124FF6C8400C032ED /* LaunchScreen.storyboard in Resources */, 189 | B1505499269C92B700EBDA4B /* AppConfigurationDevelopment1.plist in Resources */, 190 | B10E262E24FF6C8400C032ED /* Assets.xcassets in Resources */, 191 | B1595504267CB97A00D0BD76 /* AppConfigurationDevelopment.plist in Resources */, 192 | ); 193 | runOnlyForDeploymentPostprocessing = 0; 194 | }; 195 | /* End PBXResourcesBuildPhase section */ 196 | 197 | /* Begin PBXShellScriptBuildPhase section */ 198 | B01AB787D93A1A61A830D7A3 /* [CP] Check Pods Manifest.lock */ = { 199 | isa = PBXShellScriptBuildPhase; 200 | buildActionMask = 2147483647; 201 | files = ( 202 | ); 203 | inputFileListPaths = ( 204 | ); 205 | inputPaths = ( 206 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 207 | "${PODS_ROOT}/Manifest.lock", 208 | ); 209 | name = "[CP] Check Pods Manifest.lock"; 210 | outputFileListPaths = ( 211 | ); 212 | outputPaths = ( 213 | "$(DERIVED_FILE_DIR)/Pods-Catalyst-iOS-SDK-Sample-App-checkManifestLockResult.txt", 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | shellPath = /bin/sh; 217 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 218 | showEnvVarsInLog = 0; 219 | }; 220 | D65CFDC2FFB10653DFB5CFA2 /* [CP] Embed Pods Frameworks */ = { 221 | isa = PBXShellScriptBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | ); 225 | inputFileListPaths = ( 226 | "${PODS_ROOT}/Target Support Files/Pods-Catalyst-iOS-SDK-Sample-App/Pods-Catalyst-iOS-SDK-Sample-App-frameworks-${CONFIGURATION}-input-files.xcfilelist", 227 | ); 228 | name = "[CP] Embed Pods Frameworks"; 229 | outputFileListPaths = ( 230 | "${PODS_ROOT}/Target Support Files/Pods-Catalyst-iOS-SDK-Sample-App/Pods-Catalyst-iOS-SDK-Sample-App-frameworks-${CONFIGURATION}-output-files.xcfilelist", 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | shellPath = /bin/sh; 234 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Catalyst-iOS-SDK-Sample-App/Pods-Catalyst-iOS-SDK-Sample-App-frameworks.sh\"\n"; 235 | showEnvVarsInLog = 0; 236 | }; 237 | /* End PBXShellScriptBuildPhase section */ 238 | 239 | /* Begin PBXSourcesBuildPhase section */ 240 | B10E261D24FF6C8100C032ED /* Sources */ = { 241 | isa = PBXSourcesBuildPhase; 242 | buildActionMask = 2147483647; 243 | files = ( 244 | B10E266D25024D4100C032ED /* ListViewController.swift in Sources */, 245 | B1FD2CAB250FA87400CB36FC /* CommonUtil.swift in Sources */, 246 | B1EF6E7A250F99530023DCB5 /* TextFieldCell.swift in Sources */, 247 | B179EABF2509257000AE0779 /* Field.swift in Sources */, 248 | B179EABD2507C3FA00AE0779 /* DetailViewController.swift in Sources */, 249 | B10E262524FF6C8100C032ED /* AppDelegate.swift in Sources */, 250 | B1EF6E78250B8A310023DCB5 /* CreateController.swift in Sources */, 251 | B124F887250B5AF50014028C /* AddRowCell.swift in Sources */, 252 | B179EAC1250A5EB500AE0779 /* BooleanField.swift in Sources */, 253 | B10E26392500F3DF00C032ED /* HomeController.swift in Sources */, 254 | B179EAC3250A73BC00AE0779 /* ForeignKeyField.swift in Sources */, 255 | B1F50C79251A3B94002F7385 /* ButtonFieldCell.swift in Sources */, 256 | ); 257 | runOnlyForDeploymentPostprocessing = 0; 258 | }; 259 | /* End PBXSourcesBuildPhase section */ 260 | 261 | /* Begin PBXVariantGroup section */ 262 | B10E262F24FF6C8400C032ED /* LaunchScreen.storyboard */ = { 263 | isa = PBXVariantGroup; 264 | children = ( 265 | B10E263024FF6C8400C032ED /* Base */, 266 | ); 267 | name = LaunchScreen.storyboard; 268 | sourceTree = ""; 269 | }; 270 | /* End PBXVariantGroup section */ 271 | 272 | /* Begin XCBuildConfiguration section */ 273 | B10E263324FF6C8400C032ED /* Debug */ = { 274 | isa = XCBuildConfiguration; 275 | buildSettings = { 276 | ALWAYS_SEARCH_USER_PATHS = NO; 277 | CLANG_ANALYZER_NONNULL = YES; 278 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 279 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 280 | CLANG_CXX_LIBRARY = "libc++"; 281 | CLANG_ENABLE_MODULES = YES; 282 | CLANG_ENABLE_OBJC_ARC = YES; 283 | CLANG_ENABLE_OBJC_WEAK = YES; 284 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 285 | CLANG_WARN_BOOL_CONVERSION = YES; 286 | CLANG_WARN_COMMA = YES; 287 | CLANG_WARN_CONSTANT_CONVERSION = YES; 288 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 289 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 290 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 291 | CLANG_WARN_EMPTY_BODY = YES; 292 | CLANG_WARN_ENUM_CONVERSION = YES; 293 | CLANG_WARN_INFINITE_RECURSION = YES; 294 | CLANG_WARN_INT_CONVERSION = YES; 295 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 296 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 297 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 298 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 299 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 300 | CLANG_WARN_STRICT_PROTOTYPES = YES; 301 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 302 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 303 | CLANG_WARN_UNREACHABLE_CODE = YES; 304 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 305 | COPY_PHASE_STRIP = NO; 306 | DEBUG_INFORMATION_FORMAT = dwarf; 307 | ENABLE_STRICT_OBJC_MSGSEND = YES; 308 | ENABLE_TESTABILITY = YES; 309 | GCC_C_LANGUAGE_STANDARD = gnu11; 310 | GCC_DYNAMIC_NO_PIC = NO; 311 | GCC_NO_COMMON_BLOCKS = YES; 312 | GCC_OPTIMIZATION_LEVEL = 0; 313 | GCC_PREPROCESSOR_DEFINITIONS = ( 314 | "DEBUG=1", 315 | "$(inherited)", 316 | ); 317 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 318 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 319 | GCC_WARN_UNDECLARED_SELECTOR = YES; 320 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 321 | GCC_WARN_UNUSED_FUNCTION = YES; 322 | GCC_WARN_UNUSED_VARIABLE = YES; 323 | IPHONEOS_DEPLOYMENT_TARGET = 13.6; 324 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 325 | MTL_FAST_MATH = YES; 326 | ONLY_ACTIVE_ARCH = YES; 327 | SDKROOT = iphoneos; 328 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 329 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 330 | }; 331 | name = Debug; 332 | }; 333 | B10E263424FF6C8400C032ED /* Release */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | ALWAYS_SEARCH_USER_PATHS = NO; 337 | CLANG_ANALYZER_NONNULL = YES; 338 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 339 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 340 | CLANG_CXX_LIBRARY = "libc++"; 341 | CLANG_ENABLE_MODULES = YES; 342 | CLANG_ENABLE_OBJC_ARC = YES; 343 | CLANG_ENABLE_OBJC_WEAK = YES; 344 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 345 | CLANG_WARN_BOOL_CONVERSION = YES; 346 | CLANG_WARN_COMMA = YES; 347 | CLANG_WARN_CONSTANT_CONVERSION = YES; 348 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 349 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 350 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 351 | CLANG_WARN_EMPTY_BODY = YES; 352 | CLANG_WARN_ENUM_CONVERSION = YES; 353 | CLANG_WARN_INFINITE_RECURSION = YES; 354 | CLANG_WARN_INT_CONVERSION = YES; 355 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 356 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 357 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 358 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 359 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 360 | CLANG_WARN_STRICT_PROTOTYPES = YES; 361 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 362 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 363 | CLANG_WARN_UNREACHABLE_CODE = YES; 364 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 365 | COPY_PHASE_STRIP = NO; 366 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 367 | ENABLE_NS_ASSERTIONS = NO; 368 | ENABLE_STRICT_OBJC_MSGSEND = YES; 369 | GCC_C_LANGUAGE_STANDARD = gnu11; 370 | GCC_NO_COMMON_BLOCKS = YES; 371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 373 | GCC_WARN_UNDECLARED_SELECTOR = YES; 374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 375 | GCC_WARN_UNUSED_FUNCTION = YES; 376 | GCC_WARN_UNUSED_VARIABLE = YES; 377 | IPHONEOS_DEPLOYMENT_TARGET = 13.6; 378 | MTL_ENABLE_DEBUG_INFO = NO; 379 | MTL_FAST_MATH = YES; 380 | SDKROOT = iphoneos; 381 | SWIFT_COMPILATION_MODE = wholemodule; 382 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 383 | VALIDATE_PRODUCT = YES; 384 | }; 385 | name = Release; 386 | }; 387 | B10E263624FF6C8400C032ED /* Debug */ = { 388 | isa = XCBuildConfiguration; 389 | baseConfigurationReference = BE956A02CEE1835D527848D0 /* Pods-Catalyst-iOS-SDK-Sample-App.debug.xcconfig */; 390 | buildSettings = { 391 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 392 | CODE_SIGN_IDENTITY = "Apple Development"; 393 | CODE_SIGN_STYLE = Automatic; 394 | DEVELOPMENT_TEAM = MK5V4DPPVM; 395 | ENABLE_BITCODE = NO; 396 | INFOPLIST_FILE = "Catalyst-iOS-SDK-Sample-App/Info.plist"; 397 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 398 | LD_RUNPATH_SEARCH_PATHS = ( 399 | "$(inherited)", 400 | "@executable_path/Frameworks", 401 | ); 402 | PRODUCT_BUNDLE_IDENTIFIER = "com.zoho.catalyst.SDKSampleApp-"; 403 | PRODUCT_NAME = "$(TARGET_NAME)"; 404 | PROVISIONING_PROFILE_SPECIFIER = ""; 405 | SWIFT_VERSION = 5.0; 406 | TARGETED_DEVICE_FAMILY = "1,2"; 407 | }; 408 | name = Debug; 409 | }; 410 | B10E263724FF6C8400C032ED /* Release */ = { 411 | isa = XCBuildConfiguration; 412 | baseConfigurationReference = 9099E6CD979B60F312E4B508 /* Pods-Catalyst-iOS-SDK-Sample-App.release.xcconfig */; 413 | buildSettings = { 414 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 415 | CODE_SIGN_IDENTITY = "Apple Development"; 416 | CODE_SIGN_STYLE = Automatic; 417 | DEVELOPMENT_TEAM = MK5V4DPPVM; 418 | ENABLE_BITCODE = NO; 419 | INFOPLIST_FILE = "Catalyst-iOS-SDK-Sample-App/Info.plist"; 420 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 421 | LD_RUNPATH_SEARCH_PATHS = ( 422 | "$(inherited)", 423 | "@executable_path/Frameworks", 424 | ); 425 | PRODUCT_BUNDLE_IDENTIFIER = "com.zoho.catalyst.SDKSampleApp-"; 426 | PRODUCT_NAME = "$(TARGET_NAME)"; 427 | PROVISIONING_PROFILE_SPECIFIER = ""; 428 | SWIFT_VERSION = 5.0; 429 | TARGETED_DEVICE_FAMILY = "1,2"; 430 | }; 431 | name = Release; 432 | }; 433 | /* End XCBuildConfiguration section */ 434 | 435 | /* Begin XCConfigurationList section */ 436 | B10E261C24FF6C8100C032ED /* Build configuration list for PBXProject "Catalyst-iOS-SDK-Sample-App" */ = { 437 | isa = XCConfigurationList; 438 | buildConfigurations = ( 439 | B10E263324FF6C8400C032ED /* Debug */, 440 | B10E263424FF6C8400C032ED /* Release */, 441 | ); 442 | defaultConfigurationIsVisible = 0; 443 | defaultConfigurationName = Release; 444 | }; 445 | B10E263524FF6C8400C032ED /* Build configuration list for PBXNativeTarget "Catalyst-iOS-SDK-Sample-App" */ = { 446 | isa = XCConfigurationList; 447 | buildConfigurations = ( 448 | B10E263624FF6C8400C032ED /* Debug */, 449 | B10E263724FF6C8400C032ED /* Release */, 450 | ); 451 | defaultConfigurationIsVisible = 0; 452 | defaultConfigurationName = Release; 453 | }; 454 | /* End XCConfigurationList section */ 455 | }; 456 | rootObject = B10E261924FF6C8100C032ED /* Project object */; 457 | } 458 | --------------------------------------------------------------------------------