├── .gitignore ├── .rspec ├── .travis.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── VIPERGenDemo ├── VIPERGenDemo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── VIPERGenDemo │ ├── AppDelegate.swift │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── Info.plist │ └── ViewController.swift └── VIPERGenDemoTests │ ├── Info.plist │ └── VIPERGenDemoTests.swift ├── bin └── vipergen ├── lib ├── templates │ └── default │ │ ├── objc │ │ ├── DataManager │ │ │ ├── VIPERDataManager.h │ │ │ └── VIPERDataManager.m │ │ ├── Interactor │ │ │ ├── VIPERInteractor.h │ │ │ └── VIPERInteractor.m │ │ ├── Presenter │ │ │ ├── VIPERPresenter.h │ │ │ └── VIPERPresenter.m │ │ ├── Protocols │ │ │ └── VIPERProtocols.h │ │ ├── ViewController │ │ │ ├── VIPERViewController.h │ │ │ └── VIPERViewController.m │ │ └── WireFrame │ │ │ ├── VIPERWireFrame.h │ │ │ └── VIPERWireFrame.m │ │ ├── swift │ │ └── Protocols │ │ │ └── VIPERProtocols.swift │ │ └── viperspec.yml ├── vipergen.rb └── vipergen │ ├── dirutils.rb │ ├── filemanager.rb │ ├── generator.rb │ ├── templatemanager.rb │ ├── version.rb │ └── viperthor.rb ├── rakefile ├── slides └── viper_slides_codemotion.key │ ├── Data │ ├── 11030946903_6579e3c9a1_o-106.jpg │ ├── 11030946903_6579e3c9a1_o-small-107.jpg │ ├── PresetImageFill0-1.jpg │ ├── PresetImageFill1-2.jpg │ ├── PresetImageFill2-3.jpg │ ├── PresetImageFill3-4.jpg │ ├── PresetImageFill4-5.jpg │ ├── PresetImageFill5-6.jpg │ ├── image00-9.png │ ├── image00-small-10.png │ ├── image02-18.jpg │ ├── image02-small-19.jpg │ ├── mt0@2x-20.jpg │ ├── mt1@2x-21.jpg │ ├── mt2@2x-22.jpg │ ├── mt4@2x-23.jpg │ ├── mt5@2x-24.jpg │ ├── mt6@2x-25.jpg │ ├── pasted-image-49.png │ ├── st0-150.jpg │ ├── st1-27.jpg │ ├── st2-28.jpg │ ├── st3-29.jpg │ ├── st4-30.jpg │ └── st5-31.jpg │ ├── Index.zip │ ├── Metadata │ ├── BuildVersionHistory.plist │ ├── DocumentIdentifier │ └── Properties.plist │ ├── preview-micro.jpg │ ├── preview-web.jpg │ └── preview.jpg ├── spec ├── spec_helper.rb └── vipergen │ └── vipergen_spec.rb └── vipergen.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by http://www.gitignore.io 2 | 3 | ### Ruby ### 4 | *.gem 5 | *.rbc 6 | /.config 7 | /coverage/ 8 | /InstalledFiles 9 | /pkg/ 10 | /spec/reports/ 11 | /test/tmp/ 12 | /test/version_tmp/ 13 | /tmp/ 14 | 15 | ## Specific to RubyMotion: 16 | .dat* 17 | .repl_history 18 | build/ 19 | 20 | ## Documentation cache and generated files: 21 | /.yardoc/ 22 | /_yardoc/ 23 | /doc/ 24 | /rdoc/ 25 | 26 | ## Environment normalisation: 27 | /.bundle/ 28 | /lib/bundler/man/ 29 | 30 | # for a library or gem, you might want to ignore these files since the code is 31 | # intended to run in multiple environments; otherwise, check them in: 32 | # Gemfile.lock 33 | # .ruby-version 34 | # .ruby-gemset 35 | 36 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 37 | .rvmrc 38 | 39 | 40 | ### SublimeText ### 41 | # workspace files are user-specific 42 | *.sublime-workspace 43 | 44 | # project files should be checked into the repository, unless a significant 45 | # proportion of contributors will probably not be using SublimeText 46 | # *.sublime-project 47 | 48 | #sftp configuration file 49 | sftp-config.json 50 | 51 | 52 | ### OSX ### 53 | .DS_Store 54 | .AppleDouble 55 | .LSOverride 56 | 57 | # Icon must end with two \r 58 | Icon 59 | 60 | 61 | # Thumbnails 62 | ._* 63 | 64 | # Files that might appear on external disk 65 | .Spotlight-V100 66 | .Trashes 67 | 68 | # Directories potentially created on remote AFP share 69 | .AppleDB 70 | .AppleDesktop 71 | Network Trash Folder 72 | Temporary Items 73 | .apdisk 74 | 75 | 76 | ### Objective-C ### 77 | # Xcode 78 | # 79 | build/ 80 | *.pbxuser 81 | !default.pbxuser 82 | *.mode1v3 83 | !default.mode1v3 84 | *.mode2v3 85 | !default.mode2v3 86 | *.perspectivev3 87 | !default.perspectivev3 88 | xcuserdata 89 | *.xccheckout 90 | *.moved-aside 91 | DerivedData 92 | *.hmap 93 | *.ipa 94 | *.xcuserstate 95 | 96 | # CocoaPods 97 | # 98 | # We recommend against adding the Pods directory to your .gitignore. However 99 | # you should judge for yourself, the pros and cons are mentioned at: 100 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 101 | # 102 | # Pods/ 103 | 104 | 105 | ### Swift ### 106 | # Xcode 107 | # 108 | build/ 109 | *.pbxuser 110 | !default.pbxuser 111 | *.mode1v3 112 | !default.mode1v3 113 | *.mode2v3 114 | !default.mode2v3 115 | *.perspectivev3 116 | !default.perspectivev3 117 | xcuserdata 118 | *.xccheckout 119 | *.moved-aside 120 | DerivedData 121 | *.hmap 122 | *.ipa 123 | *.xcuserstate 124 | 125 | # CocoaPods 126 | # 127 | # We recommend against adding the Pods directory to your .gitignore. However 128 | # you should judge for yourself, the pros and cons are mentioned at: 129 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 130 | # 131 | # Pods/ 132 | 133 | 134 | ### Xcode ### 135 | build/ 136 | *.pbxuser 137 | !default.pbxuser 138 | *.mode1v3 139 | !default.mode1v3 140 | *.mode2v3 141 | !default.mode2v3 142 | *.perspectivev3 143 | !default.perspectivev3 144 | xcuserdata 145 | *.xccheckout 146 | *.moved-aside 147 | DerivedData 148 | *.xcuserstate 149 | 150 | 151 | ### AppCode ### 152 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 153 | 154 | ## Directory-based project format 155 | .idea/ 156 | /*.iml 157 | # if you remove the above rule, at least ignore user-specific stuff: 158 | # .idea/workspace.xml 159 | # .idea/tasks.xml 160 | # .idea/dictionaries 161 | # and these sensitive or high-churn files: 162 | # .idea/dataSources.ids 163 | # .idea/dataSources.xml 164 | # .idea/sqlDataSources.xml 165 | # .idea/dynamic.xml 166 | # and, if using gradle:: 167 | # .idea/gradle.xml 168 | # .idea/libraries 169 | 170 | ## File-based project format 171 | *.ipr 172 | *.iws 173 | 174 | ## Additional for IntelliJ 175 | out/ 176 | 177 | # generated by mpeltonen/sbt-idea plugin 178 | .idea_modules/ 179 | 180 | # generated by JIRA plugin 181 | atlassian-ide-plugin.xml 182 | 183 | # generated by Crashlytics plugin (for Android Studio and Intellij) 184 | com_crashlytics_export_strings.xml 185 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format progress -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.1.0 4 | addons: 5 | code_climate: 6 | repo_token: CODECLIMATE_REPO_TOKEN -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | gem "codeclimate-test-reporter", group: :test, require: nil 6 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | vipergen (0.2.1) 5 | thor 6 | 7 | GEM 8 | remote: https://rubygems.org/ 9 | specs: 10 | byebug (3.2.0) 11 | columnize (~> 0.8) 12 | debugger-linecache (~> 1.2) 13 | codeclimate-test-reporter (0.4.0) 14 | simplecov (>= 0.7.1, < 1.0.0) 15 | columnize (0.8.9) 16 | debugger-linecache (1.2.0) 17 | diff-lcs (1.2.5) 18 | docile (1.1.5) 19 | multi_json (1.10.1) 20 | rake (10.3.2) 21 | rspec (3.0.0) 22 | rspec-core (~> 3.0.0) 23 | rspec-expectations (~> 3.0.0) 24 | rspec-mocks (~> 3.0.0) 25 | rspec-core (3.0.4) 26 | rspec-support (~> 3.0.0) 27 | rspec-expectations (3.0.4) 28 | diff-lcs (>= 1.2.0, < 2.0) 29 | rspec-support (~> 3.0.0) 30 | rspec-mocks (3.0.4) 31 | rspec-support (~> 3.0.0) 32 | rspec-support (3.0.4) 33 | simplecov (0.9.0) 34 | docile (~> 1.1.0) 35 | multi_json 36 | simplecov-html (~> 0.8.0) 37 | simplecov-html (0.8.0) 38 | thor (0.19.1) 39 | 40 | PLATFORMS 41 | ruby 42 | 43 | DEPENDENCIES 44 | bundler (~> 1.0) 45 | byebug 46 | codeclimate-test-reporter 47 | rake 48 | rspec 49 | vipergen! 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Redbooth 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Viper Module Generator 2 | ====================== 3 | 4 | ## :warning: This project is no longer maintained. 5 | 6 | Gem to generate VIPER modules to use them in your Objective-C/Swift projects 7 | The implementation scheme returned by this generator is hardly inspired in the example and post of Objc.io, http://www.objc.io/issue-13/viper.html . 8 | 9 | - [Features](#features) 10 | - [Changelog](#changelog-0.1) 11 | - [Expected in version 0.2](#expected-in-version-0.2) 12 | - [Viper files structure](#viper-files-structure) 13 | - [How to install vipergen](#how-to-install-vipergen) 14 | - [How to generate a VIPER module with a given name?](#how-to-generate-viper-module-with-a-given-name?) 15 | - [Developer tips](#developer-tips) 16 | - [Update the gem](#update-the-gem) 17 | - [Add a new template](#add-a-new-template) 18 | - [Resources](#resources) 19 | 20 | ## Features 21 | - Generates the module in Swift and Objective-C 22 | - Ready to be installed as a gem https://rubygems.org/gems/VIPERGen 23 | 24 | ### Changelog 0.1.6 25 | - Added `templates` command to know which templates are available 26 | - YAML file in each template with the information about the template (more scalable) 27 | 28 | ### Changelog 0.1 29 | - Added default template 30 | - Fully components tested 31 | 32 | ### Expected in version 0.2 33 | - Example project of Redbooth login with notifications 34 | - FetchedResultsController template 35 | - Default template in Swift 36 | - Login template 37 | - Integrate with XCode as a plugin (http://nshipster.com/xcode-plugins/) 38 | 39 | ## Viper files structure 40 | ```bash 41 | .objc 42 | +-- DataManager 43 | | +-- VIPERDataManager.h 44 | | +-- VIPERDataManager.m 45 | +-- Interactor 46 | | +-- VIPERInteractor.h 47 | | +-- VIPERInteractor.m 48 | +-- Presenter 49 | | +-- VIPERPresenter.h 50 | | +-- VIPERPresenter.m 51 | +-- ViewController 52 | | +-- VIPERViewController.h 53 | | +-- VIPERViewController.m 54 | +-- WireFrame 55 | | +-- VIPERWireFrame.h 56 | | +-- VIPERWireFrame.m 57 | +-- Protocols 58 | | +-- VIPERProtocols.h 59 | .swift 60 | +-- DataManager 61 | | +-- VIPERDataManager.swift 62 | +-- Interactor 63 | | +-- VIPERInteractor.swift 64 | +-- Presenter 65 | | +-- VIPERPresenter.swift 66 | +-- ViewController 67 | | +-- VIPERViewController.swift 68 | +-- WireFrame 69 | | +-- VIPERWireFrame.swift 70 | +-- Protocols 71 | | +-- VIPERProtocols.swift 72 | ``` 73 | ## How to install vipergen ? 74 | You can install it easily as using the gem. With ruby installed in your OSX execute: 75 | ```bash 76 | sudo gem install vipergen 77 | ``` 78 | If everything were right, you should have now the vipergem command available in your system console 79 | 80 | ## How to generate a VIPER module with a given name? 81 | You have just to execute the following command 82 | ```bash 83 | vipergen generate MyFirstViperModule --path=~/myproject/shared 84 | ``` 85 | And then the files structure will be automatically created. Don't forget to add this folder to your project dragging it into the XCode/Appcode inspector 86 | 87 | ## Developer tips 88 | ### Update the gem 89 | When the gem is updated it has to be reported to the gem repository. I followed this tutorial http://amaras-tech.co.uk/article/43/Creating_executable_gems that basically says that once you have your gem ready execute: 90 | ```bash 91 | gem build vipergen.gemspec 92 | gem install vipergen-0.1.gem 93 | gem push vipergen-0.1.gem 94 | ``` 95 | Then you'll be asked for your credentials in order to make the update in the repo (http://guides.rubygems.org/publishing/) 96 | 97 | ### Add a new template 98 | Are you interested in VIPER and you would like to contribute with this gem adding new templates? Feel free to do it. It's pretty easy. You've just to: 99 | - Create a folder inside `templates` with the name of your template 100 | - You'll have to create inside the templates in both languages, Swift and Objective-C (get inspired from existing templates) 101 | - Use the word VIPER where you want the name to be replaced in. 102 | - Remember to add the file viperspec.yml with the description of your template as below: 103 | ```yaml 104 | author: pepi 105 | author_email: pepibumur@gmail.com 106 | template_description: Default template with the simplest structure using VIPER 107 | updated_at: 2014-08-24 108 | ``` 109 | - Report it as a PR in this repo updating the gem version in Gemspec. 110 | 111 | ## Resources 112 | - Rspec documentation: http://rubydoc.info/gems/rspec-expectations/frames 113 | - XCode Plugins: http://nshipster.com/xcode-plugins/ 114 | - XCodeProj gem (to modify project groups structure): https://github.com/CocoaPods/Xcodeproj 115 | - Thor, powerful Ruby library for command line: http://whatisthor.com/ 116 | -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3D056C7D19A7881100902567 /* VIPERProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D056C7C19A7881100902567 /* VIPERProtocols.swift */; }; 11 | B749E4728976F7088B32116F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B749EA3AB3A2A76ABF088898 /* Images.xcassets */; }; 12 | B749E7DEA40F5EE82C43C1FA /* VIPERGenDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B749EA23C32AF122803CC13F /* VIPERGenDemoTests.swift */; }; 13 | B749EAC79D1784014A2BDCCB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B749E008AA7BF4ECBADA4151 /* Main.storyboard */; }; 14 | B749EBF8B846719B7113AA45 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B749EEC0EE96E7878C16C7D3 /* AppDelegate.swift */; }; 15 | B749EDF5EBFE639D631AEC38 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B749E8E7BDEC9D7FB43DCCCD /* ViewController.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXContainerItemProxy section */ 19 | B749E414B5E155EC088AD89D /* PBXContainerItemProxy */ = { 20 | isa = PBXContainerItemProxy; 21 | containerPortal = B749E8B9F6CA030919C0FE23 /* Project object */; 22 | proxyType = 1; 23 | remoteGlobalIDString = B749EFEA5470B339B4787798; 24 | remoteInfo = VIPERGenDemo; 25 | }; 26 | /* End PBXContainerItemProxy section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 3D056C7C19A7881100902567 /* VIPERProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VIPERProtocols.swift; sourceTree = ""; }; 30 | B749E1CA001F227ABD51B588 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; 31 | B749E5AD88942EB96F1BF056 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; 32 | B749E8E7BDEC9D7FB43DCCCD /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 33 | B749E942B2202F34F1367244 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 34 | B749EA23C32AF122803CC13F /* VIPERGenDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VIPERGenDemoTests.swift; sourceTree = ""; }; 35 | B749EA3AB3A2A76ABF088898 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 36 | B749EADCA40A6311ACCEA5DD /* VIPERGenDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VIPERGenDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | B749EE253B94F02DC93A0130 /* VIPERGenDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VIPERGenDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | B749EEC0EE96E7878C16C7D3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 39 | /* End PBXFileReference section */ 40 | 41 | /* Begin PBXFrameworksBuildPhase section */ 42 | B749E0FB5CB3403F02EBC79B /* Frameworks */ = { 43 | isa = PBXFrameworksBuildPhase; 44 | buildActionMask = 2147483647; 45 | files = ( 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | B749E59244C83734BA15325D /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXFrameworksBuildPhase section */ 57 | 58 | /* Begin PBXGroup section */ 59 | 3D056C4B19A7847D00902567 /* templates */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 3D056C4C19A7847D00902567 /* default */, 63 | 3D056C6519A7847D00902567 /* fetchedresults */, 64 | ); 65 | name = templates; 66 | path = ../../lib/templates; 67 | sourceTree = ""; 68 | }; 69 | 3D056C4C19A7847D00902567 /* default */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 3D056C5E19A7847D00902567 /* swift */, 73 | ); 74 | path = default; 75 | sourceTree = ""; 76 | }; 77 | 3D056C5E19A7847D00902567 /* swift */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 3D056C5F19A7847D00902567 /* DataManager */, 81 | 3D056C6019A7847D00902567 /* Interactor */, 82 | 3D056C6119A7847D00902567 /* Presenter */, 83 | 3D056C6219A7847D00902567 /* Protocols */, 84 | 3D056C6319A7847D00902567 /* ViewController */, 85 | 3D056C6419A7847D00902567 /* WireFrame */, 86 | ); 87 | path = swift; 88 | sourceTree = ""; 89 | }; 90 | 3D056C5F19A7847D00902567 /* DataManager */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | ); 94 | path = DataManager; 95 | sourceTree = ""; 96 | }; 97 | 3D056C6019A7847D00902567 /* Interactor */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | ); 101 | path = Interactor; 102 | sourceTree = ""; 103 | }; 104 | 3D056C6119A7847D00902567 /* Presenter */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | ); 108 | path = Presenter; 109 | sourceTree = ""; 110 | }; 111 | 3D056C6219A7847D00902567 /* Protocols */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 3D056C7C19A7881100902567 /* VIPERProtocols.swift */, 115 | ); 116 | path = Protocols; 117 | sourceTree = ""; 118 | }; 119 | 3D056C6319A7847D00902567 /* ViewController */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | ); 123 | path = ViewController; 124 | sourceTree = ""; 125 | }; 126 | 3D056C6419A7847D00902567 /* WireFrame */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | ); 130 | path = WireFrame; 131 | sourceTree = ""; 132 | }; 133 | 3D056C6519A7847D00902567 /* fetchedresults */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 3D056C6619A7847D00902567 /* objc */, 137 | 3D056C6D19A7847D00902567 /* swift */, 138 | ); 139 | path = fetchedresults; 140 | sourceTree = ""; 141 | }; 142 | 3D056C6619A7847D00902567 /* objc */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 3D056C6719A7847D00902567 /* DataManager */, 146 | 3D056C6819A7847D00902567 /* Interactor */, 147 | 3D056C6919A7847D00902567 /* Presenter */, 148 | 3D056C6A19A7847D00902567 /* Protocols */, 149 | 3D056C6B19A7847D00902567 /* ViewController */, 150 | 3D056C6C19A7847D00902567 /* WireFrame */, 151 | ); 152 | path = objc; 153 | sourceTree = ""; 154 | }; 155 | 3D056C6719A7847D00902567 /* DataManager */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | ); 159 | path = DataManager; 160 | sourceTree = ""; 161 | }; 162 | 3D056C6819A7847D00902567 /* Interactor */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | ); 166 | path = Interactor; 167 | sourceTree = ""; 168 | }; 169 | 3D056C6919A7847D00902567 /* Presenter */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | ); 173 | path = Presenter; 174 | sourceTree = ""; 175 | }; 176 | 3D056C6A19A7847D00902567 /* Protocols */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | ); 180 | path = Protocols; 181 | sourceTree = ""; 182 | }; 183 | 3D056C6B19A7847D00902567 /* ViewController */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | ); 187 | path = ViewController; 188 | sourceTree = ""; 189 | }; 190 | 3D056C6C19A7847D00902567 /* WireFrame */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | ); 194 | path = WireFrame; 195 | sourceTree = ""; 196 | }; 197 | 3D056C6D19A7847D00902567 /* swift */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | 3D056C6E19A7847D00902567 /* DataManager */, 201 | 3D056C6F19A7847D00902567 /* Interactor */, 202 | 3D056C7019A7847D00902567 /* Presenter */, 203 | 3D056C7119A7847D00902567 /* Protocols */, 204 | 3D056C7219A7847D00902567 /* ViewController */, 205 | 3D056C7319A7847D00902567 /* WireFrame */, 206 | ); 207 | path = swift; 208 | sourceTree = ""; 209 | }; 210 | 3D056C6E19A7847D00902567 /* DataManager */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | ); 214 | path = DataManager; 215 | sourceTree = ""; 216 | }; 217 | 3D056C6F19A7847D00902567 /* Interactor */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | ); 221 | path = Interactor; 222 | sourceTree = ""; 223 | }; 224 | 3D056C7019A7847D00902567 /* Presenter */ = { 225 | isa = PBXGroup; 226 | children = ( 227 | ); 228 | path = Presenter; 229 | sourceTree = ""; 230 | }; 231 | 3D056C7119A7847D00902567 /* Protocols */ = { 232 | isa = PBXGroup; 233 | children = ( 234 | ); 235 | path = Protocols; 236 | sourceTree = ""; 237 | }; 238 | 3D056C7219A7847D00902567 /* ViewController */ = { 239 | isa = PBXGroup; 240 | children = ( 241 | ); 242 | path = ViewController; 243 | sourceTree = ""; 244 | }; 245 | 3D056C7319A7847D00902567 /* WireFrame */ = { 246 | isa = PBXGroup; 247 | children = ( 248 | ); 249 | path = WireFrame; 250 | sourceTree = ""; 251 | }; 252 | B749E32E9C203B07FC6A4207 /* Supporting Files */ = { 253 | isa = PBXGroup; 254 | children = ( 255 | B749E1CA001F227ABD51B588 /* Info.plist */, 256 | ); 257 | name = "Supporting Files"; 258 | sourceTree = ""; 259 | }; 260 | B749E680F29C59970636F2CA /* VIPERGenDemoTests */ = { 261 | isa = PBXGroup; 262 | children = ( 263 | B749EAB36DAB99247DD084F3 /* Supporting Files */, 264 | B749EA23C32AF122803CC13F /* VIPERGenDemoTests.swift */, 265 | ); 266 | path = VIPERGenDemoTests; 267 | sourceTree = ""; 268 | }; 269 | B749EAB36DAB99247DD084F3 /* Supporting Files */ = { 270 | isa = PBXGroup; 271 | children = ( 272 | B749E5AD88942EB96F1BF056 /* Info.plist */, 273 | ); 274 | name = "Supporting Files"; 275 | sourceTree = ""; 276 | }; 277 | B749EB4BF49E039BCCBA554A /* Products */ = { 278 | isa = PBXGroup; 279 | children = ( 280 | B749EE253B94F02DC93A0130 /* VIPERGenDemo.app */, 281 | B749EADCA40A6311ACCEA5DD /* VIPERGenDemoTests.xctest */, 282 | ); 283 | name = Products; 284 | sourceTree = ""; 285 | }; 286 | B749ECADDB5E74D695C3826A /* VIPERGenDemo */ = { 287 | isa = PBXGroup; 288 | children = ( 289 | 3D056C4B19A7847D00902567 /* templates */, 290 | B749E32E9C203B07FC6A4207 /* Supporting Files */, 291 | B749EA3AB3A2A76ABF088898 /* Images.xcassets */, 292 | B749EEC0EE96E7878C16C7D3 /* AppDelegate.swift */, 293 | B749E008AA7BF4ECBADA4151 /* Main.storyboard */, 294 | B749E8E7BDEC9D7FB43DCCCD /* ViewController.swift */, 295 | ); 296 | path = VIPERGenDemo; 297 | sourceTree = ""; 298 | }; 299 | B749ED56028C113961A0F426 = { 300 | isa = PBXGroup; 301 | children = ( 302 | B749EB4BF49E039BCCBA554A /* Products */, 303 | B749ECADDB5E74D695C3826A /* VIPERGenDemo */, 304 | B749E680F29C59970636F2CA /* VIPERGenDemoTests */, 305 | ); 306 | sourceTree = ""; 307 | }; 308 | /* End PBXGroup section */ 309 | 310 | /* Begin PBXNativeTarget section */ 311 | B749E92E03356EE8881A8183 /* VIPERGenDemoTests */ = { 312 | isa = PBXNativeTarget; 313 | buildConfigurationList = B749E46D88F08347B00F9463 /* Build configuration list for PBXNativeTarget "VIPERGenDemoTests" */; 314 | buildPhases = ( 315 | B749EC426822E26FC7638A09 /* Sources */, 316 | B749E59244C83734BA15325D /* Frameworks */, 317 | B749EA81256137463932A1FE /* Resources */, 318 | ); 319 | buildRules = ( 320 | ); 321 | dependencies = ( 322 | B749EBA31899CCD140B3E134 /* PBXTargetDependency */, 323 | ); 324 | name = VIPERGenDemoTests; 325 | productName = VIPERGenDemoTests; 326 | productReference = B749EADCA40A6311ACCEA5DD /* VIPERGenDemoTests.xctest */; 327 | productType = "com.apple.product-type.bundle.unit-test"; 328 | }; 329 | B749EFEA5470B339B4787798 /* VIPERGenDemo */ = { 330 | isa = PBXNativeTarget; 331 | buildConfigurationList = B749EF3BAE8B9CAA3966C704 /* Build configuration list for PBXNativeTarget "VIPERGenDemo" */; 332 | buildPhases = ( 333 | B749E8C31E6F7F2D1C236F75 /* Sources */, 334 | B749E0FB5CB3403F02EBC79B /* Frameworks */, 335 | B749EB8DF13C1F0E8E74CE8D /* Resources */, 336 | ); 337 | buildRules = ( 338 | ); 339 | dependencies = ( 340 | ); 341 | name = VIPERGenDemo; 342 | productName = VIPERGenDemo; 343 | productReference = B749EE253B94F02DC93A0130 /* VIPERGenDemo.app */; 344 | productType = "com.apple.product-type.application"; 345 | }; 346 | /* End PBXNativeTarget section */ 347 | 348 | /* Begin PBXProject section */ 349 | B749E8B9F6CA030919C0FE23 /* Project object */ = { 350 | isa = PBXProject; 351 | attributes = { 352 | ORGANIZATIONNAME = "___Redbooth___"; 353 | }; 354 | buildConfigurationList = B749E661FB627E9A7790FD49 /* Build configuration list for PBXProject "VIPERGenDemo" */; 355 | compatibilityVersion = "Xcode 3.2"; 356 | developmentRegion = English; 357 | hasScannedForEncodings = 0; 358 | knownRegions = ( 359 | en, 360 | ); 361 | mainGroup = B749ED56028C113961A0F426; 362 | productRefGroup = B749EB4BF49E039BCCBA554A /* Products */; 363 | projectDirPath = ""; 364 | projectRoot = ""; 365 | targets = ( 366 | B749EFEA5470B339B4787798 /* VIPERGenDemo */, 367 | B749E92E03356EE8881A8183 /* VIPERGenDemoTests */, 368 | ); 369 | }; 370 | /* End PBXProject section */ 371 | 372 | /* Begin PBXResourcesBuildPhase section */ 373 | B749EA81256137463932A1FE /* Resources */ = { 374 | isa = PBXResourcesBuildPhase; 375 | buildActionMask = 2147483647; 376 | files = ( 377 | ); 378 | runOnlyForDeploymentPostprocessing = 0; 379 | }; 380 | B749EB8DF13C1F0E8E74CE8D /* Resources */ = { 381 | isa = PBXResourcesBuildPhase; 382 | buildActionMask = 2147483647; 383 | files = ( 384 | B749E4728976F7088B32116F /* Images.xcassets in Resources */, 385 | B749EAC79D1784014A2BDCCB /* Main.storyboard in Resources */, 386 | ); 387 | runOnlyForDeploymentPostprocessing = 0; 388 | }; 389 | /* End PBXResourcesBuildPhase section */ 390 | 391 | /* Begin PBXSourcesBuildPhase section */ 392 | B749E8C31E6F7F2D1C236F75 /* Sources */ = { 393 | isa = PBXSourcesBuildPhase; 394 | buildActionMask = 2147483647; 395 | files = ( 396 | B749EBF8B846719B7113AA45 /* AppDelegate.swift in Sources */, 397 | B749EDF5EBFE639D631AEC38 /* ViewController.swift in Sources */, 398 | 3D056C7D19A7881100902567 /* VIPERProtocols.swift in Sources */, 399 | ); 400 | runOnlyForDeploymentPostprocessing = 0; 401 | }; 402 | B749EC426822E26FC7638A09 /* Sources */ = { 403 | isa = PBXSourcesBuildPhase; 404 | buildActionMask = 2147483647; 405 | files = ( 406 | B749E7DEA40F5EE82C43C1FA /* VIPERGenDemoTests.swift in Sources */, 407 | ); 408 | runOnlyForDeploymentPostprocessing = 0; 409 | }; 410 | /* End PBXSourcesBuildPhase section */ 411 | 412 | /* Begin PBXTargetDependency section */ 413 | B749EBA31899CCD140B3E134 /* PBXTargetDependency */ = { 414 | isa = PBXTargetDependency; 415 | target = B749EFEA5470B339B4787798 /* VIPERGenDemo */; 416 | targetProxy = B749E414B5E155EC088AD89D /* PBXContainerItemProxy */; 417 | }; 418 | /* End PBXTargetDependency section */ 419 | 420 | /* Begin PBXVariantGroup section */ 421 | B749E008AA7BF4ECBADA4151 /* Main.storyboard */ = { 422 | isa = PBXVariantGroup; 423 | children = ( 424 | B749E942B2202F34F1367244 /* Base */, 425 | ); 426 | name = Main.storyboard; 427 | sourceTree = ""; 428 | }; 429 | /* End PBXVariantGroup section */ 430 | 431 | /* Begin XCBuildConfiguration section */ 432 | B749E100A11901D5AE4EA330 /* Debug */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 436 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 437 | INFOPLIST_FILE = VIPERGenDemo/Info.plist; 438 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 439 | PRODUCT_NAME = "$(TARGET_NAME)"; 440 | }; 441 | name = Debug; 442 | }; 443 | B749E1DBB8D33E0EA8E8F2F0 /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | ALWAYS_SEARCH_USER_PATHS = NO; 447 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 448 | CLANG_CXX_LIBRARY = "libc++"; 449 | CLANG_ENABLE_MODULES = YES; 450 | CLANG_ENABLE_OBJC_ARC = YES; 451 | CLANG_WARN_BOOL_CONVERSION = YES; 452 | CLANG_WARN_CONSTANT_CONVERSION = YES; 453 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 454 | CLANG_WARN_EMPTY_BODY = YES; 455 | CLANG_WARN_ENUM_CONVERSION = YES; 456 | CLANG_WARN_INT_CONVERSION = YES; 457 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 458 | CLANG_WARN_UNREACHABLE_CODE = YES; 459 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 460 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 461 | COPY_PHASE_STRIP = YES; 462 | ENABLE_NS_ASSERTIONS = NO; 463 | ENABLE_STRICT_OBJC_MSGSEND = YES; 464 | GCC_C_LANGUAGE_STANDARD = gnu99; 465 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 466 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 467 | GCC_WARN_UNDECLARED_SELECTOR = YES; 468 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 469 | GCC_WARN_UNUSED_FUNCTION = YES; 470 | GCC_WARN_UNUSED_VARIABLE = YES; 471 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 472 | MTL_ENABLE_DEBUG_INFO = NO; 473 | SDKROOT = iphoneos; 474 | TARGETED_DEVICE_FAMILY = "1,2"; 475 | VALIDATE_PRODUCT = YES; 476 | }; 477 | name = Release; 478 | }; 479 | B749E2CAC770322B9CF0FF0E /* Debug */ = { 480 | isa = XCBuildConfiguration; 481 | buildSettings = { 482 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/VIPERGenDemo.app/VIPERGenDemo"; 483 | FRAMEWORK_SEARCH_PATHS = ( 484 | "$(SDKROOT)/Developer/Library/Frameworks", 485 | "$(inherited)", 486 | ); 487 | INFOPLIST_FILE = VIPERGenDemoTests/Info.plist; 488 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 489 | PRODUCT_NAME = "$(TARGET_NAME)"; 490 | TEST_HOST = "$(BUNDLE_LOADER)"; 491 | }; 492 | name = Debug; 493 | }; 494 | B749E52B863A23D163C8D370 /* Release */ = { 495 | isa = XCBuildConfiguration; 496 | buildSettings = { 497 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/VIPERGenDemo.app/VIPERGenDemo"; 498 | FRAMEWORK_SEARCH_PATHS = ( 499 | "$(SDKROOT)/Developer/Library/Frameworks", 500 | "$(inherited)", 501 | ); 502 | INFOPLIST_FILE = VIPERGenDemoTests/Info.plist; 503 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 504 | PRODUCT_NAME = "$(TARGET_NAME)"; 505 | TEST_HOST = "$(BUNDLE_LOADER)"; 506 | }; 507 | name = Release; 508 | }; 509 | B749E86A30E7C306090BFB2C /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | buildSettings = { 512 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 513 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 514 | INFOPLIST_FILE = VIPERGenDemo/Info.plist; 515 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 516 | PRODUCT_NAME = "$(TARGET_NAME)"; 517 | }; 518 | name = Release; 519 | }; 520 | B749EB29682B25CAFCE05595 /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | buildSettings = { 523 | ALWAYS_SEARCH_USER_PATHS = NO; 524 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 525 | CLANG_CXX_LIBRARY = "libc++"; 526 | CLANG_ENABLE_MODULES = YES; 527 | CLANG_ENABLE_OBJC_ARC = YES; 528 | CLANG_WARN_BOOL_CONVERSION = YES; 529 | CLANG_WARN_CONSTANT_CONVERSION = YES; 530 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 531 | CLANG_WARN_EMPTY_BODY = YES; 532 | CLANG_WARN_ENUM_CONVERSION = YES; 533 | CLANG_WARN_INT_CONVERSION = YES; 534 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 535 | CLANG_WARN_UNREACHABLE_CODE = YES; 536 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 537 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 538 | COPY_PHASE_STRIP = NO; 539 | ENABLE_STRICT_OBJC_MSGSEND = YES; 540 | GCC_C_LANGUAGE_STANDARD = gnu99; 541 | GCC_DYNAMIC_NO_PIC = NO; 542 | GCC_OPTIMIZATION_LEVEL = 0; 543 | GCC_PREPROCESSOR_DEFINITIONS = ( 544 | "DEBUG=1", 545 | "$(inherited)", 546 | ); 547 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 548 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 549 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 550 | GCC_WARN_UNDECLARED_SELECTOR = YES; 551 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 552 | GCC_WARN_UNUSED_FUNCTION = YES; 553 | GCC_WARN_UNUSED_VARIABLE = YES; 554 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 555 | MTL_ENABLE_DEBUG_INFO = YES; 556 | ONLY_ACTIVE_ARCH = YES; 557 | SDKROOT = iphoneos; 558 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 559 | TARGETED_DEVICE_FAMILY = "1,2"; 560 | }; 561 | name = Debug; 562 | }; 563 | /* End XCBuildConfiguration section */ 564 | 565 | /* Begin XCConfigurationList section */ 566 | B749E46D88F08347B00F9463 /* Build configuration list for PBXNativeTarget "VIPERGenDemoTests" */ = { 567 | isa = XCConfigurationList; 568 | buildConfigurations = ( 569 | B749E2CAC770322B9CF0FF0E /* Debug */, 570 | B749E52B863A23D163C8D370 /* Release */, 571 | ); 572 | defaultConfigurationIsVisible = 0; 573 | defaultConfigurationName = Release; 574 | }; 575 | B749E661FB627E9A7790FD49 /* Build configuration list for PBXProject "VIPERGenDemo" */ = { 576 | isa = XCConfigurationList; 577 | buildConfigurations = ( 578 | B749EB29682B25CAFCE05595 /* Debug */, 579 | B749E1DBB8D33E0EA8E8F2F0 /* Release */, 580 | ); 581 | defaultConfigurationIsVisible = 0; 582 | defaultConfigurationName = Release; 583 | }; 584 | B749EF3BAE8B9CAA3966C704 /* Build configuration list for PBXNativeTarget "VIPERGenDemo" */ = { 585 | isa = XCConfigurationList; 586 | buildConfigurations = ( 587 | B749E100A11901D5AE4EA330 /* Debug */, 588 | B749E86A30E7C306090BFB2C /* Release */, 589 | ); 590 | defaultConfigurationIsVisible = 0; 591 | defaultConfigurationName = Release; 592 | }; 593 | /* End XCConfigurationList section */ 594 | }; 595 | rootObject = B749E8B9F6CA030919C0FE23 /* Project object */; 596 | } 597 | -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // VIPERGenDemo 4 | // 5 | // Created by Pedro Piñera Buendía on 22/08/14. 6 | // Copyright (c) 2014 ___Redbooth___. All rights reserved. 7 | // 8 | 9 | 10 | import UIKit 11 | 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate { 15 | 16 | 17 | var window: UIWindow? 18 | 19 | 20 | 21 | 22 | func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool { 23 | // Override point for customization after application launch. 24 | return true 25 | } 26 | 27 | 28 | func applicationWillResignActive(application: UIApplication!) { 29 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 30 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 31 | 32 | } 33 | 34 | 35 | func applicationDidEnterBackground(application: UIApplication!) { 36 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 38 | 39 | } 40 | 41 | 42 | func applicationWillEnterForeground(application: UIApplication!) { 43 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 44 | } 45 | 46 | 47 | func applicationDidBecomeActive(application: UIApplication!) { 48 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 49 | } 50 | 51 | 52 | func applicationWillTerminate(application: UIApplication!) { 53 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 54 | } 55 | 56 | 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemo/Base.lproj/Main.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 | -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CFBundleIdentifier 7 | com.Redbooth.$(PRODUCT_NAME:rfc1034identifier) 8 | CFBundleInfoDictionaryVersion 9 | 6.0 10 | CFBundleSignature 11 | ???? 12 | 13 | CFBundleExecutable 14 | $(EXECUTABLE_NAME) 15 | 16 | CFBundleName 17 | $(PRODUCT_NAME) 18 | 19 | CFBundleDevelopmentRegion 20 | en 21 | 22 | CFBundleShortVersionString 23 | 1.0 24 | CFBundleVersion 25 | 1 26 | 27 | CFBundlePackageType 28 | APPL 29 | 30 | LSRequiresIPhoneOS 31 | 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | UIMainStoryboardFile 50 | Main 51 | 52 | -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // VIPERGenDemo 4 | // 5 | // Created by Pedro Piñera Buendía on 22/08/14. 6 | // Copyright (c) 2014 ___Redbooth___. All rights reserved. 7 | // 8 | 9 | 10 | import UIKit 11 | 12 | 13 | class ViewController: UIViewController { 14 | 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | // Do any additional setup after loading the view, typically from a nib. 19 | } 20 | 21 | 22 | override func didReceiveMemoryWarning() { 23 | super.didReceiveMemoryWarning() 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CFBundleIdentifier 7 | com.Redbooth.$(PRODUCT_NAME:rfc1034identifier) 8 | CFBundleInfoDictionaryVersion 9 | 6.0 10 | CFBundleSignature 11 | ???? 12 | 13 | CFBundleExecutable 14 | $(EXECUTABLE_NAME) 15 | 16 | CFBundleName 17 | $(PRODUCT_NAME) 18 | 19 | CFBundleDevelopmentRegion 20 | en 21 | 22 | CFBundleShortVersionString 23 | 1.0 24 | CFBundleVersion 25 | 1 26 | 27 | CFBundlePackageType 28 | BNDL 29 | 30 | 31 | -------------------------------------------------------------------------------- /VIPERGenDemo/VIPERGenDemoTests/VIPERGenDemoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VIPERGenDemoTests.swift 3 | // VIPERGenDemoTests 4 | // 5 | // Created by Pedro Piñera Buendía on 22/08/14. 6 | // Copyright (c) 2014 ___Redbooth___. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class VIPERGenDemoTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /bin/vipergen: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | #require 'rubygems' 4 | require 'vipergen/viperthor' 5 | 6 | puts "------- VIPER GENERATOR---------\n" 7 | puts ARGV 8 | Vipergen::ViperThor.start(ARGV) 9 | puts "--------------------------------\n" -------------------------------------------------------------------------------- /lib/templates/default/objc/DataManager/VIPERDataManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import 7 | #import "VIPERProtocols.h" 8 | 9 | 10 | @interface VIPERDataManager : NSObject 11 | 12 | // Properties 13 | @property (nonatomic, weak) id interactor; 14 | 15 | @end -------------------------------------------------------------------------------- /lib/templates/default/objc/DataManager/VIPERDataManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import "VIPERDataManager.h" 7 | 8 | 9 | @implementation VIPERDataManager 10 | 11 | @end -------------------------------------------------------------------------------- /lib/templates/default/objc/Interactor/VIPERInteractor.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import 7 | #import "VIPERProtocols.h" 8 | 9 | 10 | @interface VIPERInteractor : NSObject 11 | 12 | // Properties 13 | @property (nonatomic, weak) id presenter; 14 | @property (nonatomic, strong) id dataManager; 15 | 16 | @end -------------------------------------------------------------------------------- /lib/templates/default/objc/Interactor/VIPERInteractor.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import "VIPERInteractor.h" 7 | 8 | @implementation VIPERInteractor 9 | 10 | @end -------------------------------------------------------------------------------- /lib/templates/default/objc/Presenter/VIPERPresenter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import 7 | #import "VIPERProtocols.h" 8 | 9 | @class VIPERWireFrame; 10 | 11 | @interface VIPERPresenter : NSObject 12 | 13 | // Properties 14 | @property (nonatomic, weak) id view; 15 | @property (nonatomic, strong) id interactor; 16 | @property (nonatomic, strong) VIPERWireFrame *wireFrame; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /lib/templates/default/objc/Presenter/VIPERPresenter.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import "VIPERPresenter.h" 7 | #import "VIPERWireframe.h" 8 | 9 | @implementation VIPERPresenter 10 | 11 | @end -------------------------------------------------------------------------------- /lib/templates/default/objc/Protocols/VIPERProtocols.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import 7 | #import 8 | 9 | @protocol VIPERDataManagerOutputProtocol; 10 | @protocol VIPERInteractorOutputProtocol; 11 | @protocol VIPERInteractorInputProtocol; 12 | @protocol VIPERViewProtocol; 13 | @protocol VIPERPresenterProtocol; 14 | @protocol VIPERDataManagerInputProtocol; 15 | @class VIPERWireFrame; 16 | 17 | typedef void (^CompletionBlock)(NSError **error); 18 | 19 | @protocol VIPERViewProtocol 20 | @required 21 | @property (nonatomic, strong) id presenter; 22 | /** 23 | * Add here your methods for communication VIEWCONTROLLER -> PRESENTER 24 | */ 25 | @end 26 | 27 | @protocol VIPERPresenterProtocol 28 | @required 29 | @property (nonatomic, weak) id view; 30 | @property (nonatomic, strong) id interactor; 31 | @property (nonatomic, strong) VIPERWireFrame *wireFrame; 32 | /** 33 | * Add here your methods for communication VIEWCONTROLLER/WIREFRAME -> PRESENTER 34 | */ 35 | @end 36 | 37 | @protocol VIPERInteractorOutputProtocol 38 | /** 39 | * Add here your methods for communication INTERACTOR -> PRESENTER 40 | */ 41 | @end 42 | 43 | @protocol VIPERInteractorInputProtocol 44 | @required 45 | @property (nonatomic, weak) id presenter; 46 | /** 47 | * Add here your methods for communication PRESENTER -> INTERACTOR 48 | */ 49 | @end 50 | 51 | 52 | @protocol VIPERDataManagerInputProtocol 53 | @property (nonatomic, weak) id interactor; 54 | /** 55 | * Add here your methods for communication INTERACTOR -> DATAMANAGER 56 | */ 57 | @end 58 | 59 | @protocol VIPERDataManagerOutputProtocol 60 | @property (nonatomic, strong) id dataManager; 61 | /** 62 | * Add here your methods for communication DATAMANAGER -> INTERACTOR 63 | */ 64 | @end 65 | -------------------------------------------------------------------------------- /lib/templates/default/objc/ViewController/VIPERViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import 7 | #import "VIPERProtocols.h" 8 | 9 | @interface VIPERViewController : UIViewController 10 | 11 | @property (nonatomic, strong) id presenter; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /lib/templates/default/objc/ViewController/VIPERViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import "VIPERViewController.h" 7 | 8 | @implementation VIPERViewController 9 | 10 | #pragma mark - ViewController Lifecycle 11 | 12 | - (void)viewDidLoad 13 | { 14 | [super viewDidLoad]; 15 | } 16 | 17 | - (void)viewDidDisappear:(BOOL)animated 18 | { 19 | [super viewDidDisappear:animated]; 20 | } 21 | 22 | - (void)viewWillAppear:(BOOL)animated 23 | { 24 | [super viewWillAppear:animated]; 25 | } 26 | 27 | - (void)viewWillDisappear:(BOOL)animated 28 | { 29 | [super viewWillDisappear:animated]; 30 | } 31 | 32 | @end -------------------------------------------------------------------------------- /lib/templates/default/objc/WireFrame/VIPERWireFrame.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import 7 | #import "VIPERProtocols.h" 8 | #import "VIPERViewController.h" 9 | #import "VIPERDataManager.h" 10 | #import "VIPERInteractor.h" 11 | #import "VIPERPresenter.h" 12 | #import "VIPERWireframe.h" 13 | #import 14 | 15 | @interface VIPERWireFrame : NSObject 16 | 17 | + (void)presentVIPERModuleFrom:(id)fromView; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /lib/templates/default/objc/WireFrame/VIPERWireFrame.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Pedro Piñera Buendía on 2014. 3 | // Copyright (c) 2014 Redbooth. All rights reserved. 4 | // 5 | 6 | #import "VIPERWireFrame.h" 7 | 8 | @implementation VIPERWireFrame 9 | 10 | + (void)presentVIPERModuleFrom:(UIViewController*)fromViewController 11 | { 12 | // Generating module components 13 | UIViewController *viewController = [[VIPERViewController alloc] init]; 14 | id presenter = [VIPERPresenter new]; 15 | id interactor = [VIPERInteractor new]; 16 | id dataManager = [VIPERDataManager new]; 17 | VIPERWireFrame *wireFrame = [VIPERWireFrame new]; 18 | 19 | // Connecting 20 | viewController.presenter = presenter; 21 | presenter.view = viewController; 22 | presenter.wireFrame = wireFrame; 23 | presenter.interactor = interactor; 24 | interactor.presenter = presenter; 25 | interactor.dataManager = dataManager; 26 | dataManager.interactor = interactor; 27 | 28 | //TOODO - New view controller presentation (present, push, pop, .. ) 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /lib/templates/default/swift/Protocols/VIPERProtocols.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VIPERProtocols.swift 3 | // VIPERGenDemo 4 | // 5 | // Created by Pedro Piñera Buendía on 22/08/14. 6 | // Copyright (c) 2014 ___Redbooth___. All rights reserved. 7 | // 8 | 9 | //Problem with a bucle in protocols: http://stackoverflow.com/questions/26205809/cyclic-loop-between-protocols-in-swift 10 | 11 | protocol VIPERPresenterProtocol 12 | { 13 | var view: VIPERViewProtocol? { get set } 14 | var interactor: VIPERInteractorInputProtocol? { get set } 15 | //var wireFrame: VIPERWireFrame? { get set } 16 | 17 | // /* Add your extra communication methods here */ 18 | // /* Presenter -> ViewController */ 19 | } 20 | 21 | protocol VIPERViewProtocol 22 | { 23 | //var presenter: VIPERPresenterProtocol? { get set } 24 | } 25 | 26 | protocol VIPERDataManagerInputProtocol 27 | { 28 | var interactor: VIPERDataManagerOutputProtocol? { get set } 29 | } 30 | 31 | protocol VIPERDataManagerOutputProtocol 32 | { 33 | //var dataManager: VIPERDataManagerInputProtocol? { get set } 34 | } 35 | 36 | 37 | protocol VIPERInteractorOutputProtocol 38 | { 39 | /* Add your extra communication methods here */ 40 | /* Interactor -> Presenter */ 41 | } 42 | 43 | protocol VIPERInteractorInputProtocol 44 | { 45 | var presenter: VIPERInteractorOutputProtocol? { get set } 46 | 47 | /* Add your extra communication methods here */ 48 | /* Presenter -> Interactor */ 49 | } 50 | -------------------------------------------------------------------------------- /lib/templates/default/viperspec.yml: -------------------------------------------------------------------------------- 1 | author: pepi 2 | author_email: pepibumur@gmail.com 3 | template_description: Default template with the simplest structure using VIPER 4 | updated_at: 2014-08-24 -------------------------------------------------------------------------------- /lib/vipergen.rb: -------------------------------------------------------------------------------- 1 | require 'vipergen/generator' 2 | require 'vipergen/filemanager' 3 | require 'vipergen/dirutils' 4 | require 'vipergen/version' 5 | require 'vipergen/viperthor' 6 | require 'vipergen/templatemanager' -------------------------------------------------------------------------------- /lib/vipergen/dirutils.rb: -------------------------------------------------------------------------------- 1 | module Vipergen 2 | class DirUtils 3 | # Return a directory with the project libraries. 4 | def self.gem_libdir 5 | t = ["#{File.dirname(File.expand_path($0))}/../lib/#{Vipergen::NAME}", 6 | "#{Gem.dir}/gems/#{Vipergen::NAME}-#{Vipergen::VERSION}/lib/#{Vipergen::NAME}"] 7 | t.each {|i| return i if File.readable?(i) } 8 | raise "both paths are invalid: #{t}" 9 | end 10 | 11 | # Returns the directories inside a given one 12 | def self.directories_in(directory) 13 | expanded_dir = File.expand_path(directory) 14 | return Dir.glob(File.join(expanded_dir,'*')).select {|f| File.directory? f} 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /lib/vipergen/filemanager.rb: -------------------------------------------------------------------------------- 1 | module Vipergen 2 | # File manager class 3 | class FileManager 4 | 5 | # Returns if the template is valid by the VIPER generator 6 | def self.is_template_valid(template) 7 | return Vipergen::TemplateManager.templates.include? template 8 | end 9 | 10 | # Returns if the language is valid by the VIPER generator 11 | def self.is_language_valid(language) 12 | return (Vipergen::Generator::LANGUAGES).include? language 13 | end 14 | 15 | # Return the path if valid template and language 16 | # @return String with valid path 17 | def self.path_from(template, language) 18 | return nil if !is_language_valid(language) || !is_template_valid(template) 19 | return File.join(Vipergen::TemplateManager.templates_dir, template, language) 20 | end 21 | 22 | # Returns an array with files in a given path 23 | # @return Array with the files in a given path 24 | def self.files_in_path(path) 25 | return Dir[File.join("#{path}","/**/*")].select {|f| File.file?(f)} 26 | end 27 | 28 | # Returns the destination viper path 29 | # @return Destination root path 30 | def self.destination_viper_path(path, name) 31 | expand_path = File.expand_path(path) 32 | return File.join(expand_path,name) 33 | end 34 | 35 | # Copy a system item to another place 36 | def self.copy(from, to) 37 | to_expand_path = File.expand_path(to) 38 | from_expand_path = File.expand_path(from) 39 | FileUtils.mkdir_p (to_expand_path) 40 | FileUtils.copy_entry(from_expand_path, to_expand_path) 41 | end 42 | 43 | # Move a system item to another place 44 | def self.move(from, to) 45 | to_expand_path = File.expand_path(to) 46 | from_expand_path = File.expand_path(from) 47 | FileUtils.move(from_expand_path, to_expand_path) 48 | end 49 | 50 | end 51 | end -------------------------------------------------------------------------------- /lib/vipergen/generator.rb: -------------------------------------------------------------------------------- 1 | module Vipergen 2 | # Cosntants 3 | class Generator 4 | # Constants 5 | LANGUAGES = ["swift", "objc"] 6 | REPLACEMENT_KEY = "VIPER" 7 | 8 | # Main method that generate the VIPER files structure 9 | def self.generate_viper(template, language, name, path) 10 | puts "Generating VIPER-Module" 11 | puts "Template: #{template}" 12 | puts "Language: #{language}" 13 | puts "Name: #{name}" 14 | puts "Path: #{path}" 15 | path_from = Vipergen::FileManager.path_from(template, language) 16 | path_to = Vipergen::FileManager.destination_viper_path(path, name) 17 | Vipergen::FileManager.copy(path_from, path_to) 18 | files = Vipergen::FileManager.files_in_path(path_to) 19 | rename_files(files,name) 20 | end 21 | 22 | # Rename all the files in the files array 23 | # - It renames the name of the file 24 | # - It renames the content of the file 25 | def self.rename_files(files, name) 26 | files.each do |file| 27 | raise SyntaxError unless file.include? (Vipergen::Generator::REPLACEMENT_KEY) 28 | rename_file(file, name) 29 | end 30 | end 31 | 32 | # Rename a given file 33 | # - It renames the name of the file 34 | # - It renames the content of the file 35 | def self.rename_file(file, name) 36 | new_path = file.gsub((Vipergen::Generator::REPLACEMENT_KEY), name) 37 | Vipergen::FileManager.move(file, new_path) 38 | rename_file_content(new_path, name) 39 | end 40 | 41 | # Rename the file content 42 | # @return: An String with the every VIPER replaced by 'name' 43 | def self.rename_file_content(filename, name) 44 | # Reading content 45 | file = File.open(filename, "rb") 46 | content = file.read 47 | file.close 48 | 49 | # Replacing content 50 | content = content.gsub((Vipergen::Generator::REPLACEMENT_KEY), name) 51 | 52 | # Saving content with replaced string 53 | File.open(filename, "w+") do |file| 54 | file.write(content) 55 | end 56 | end 57 | end 58 | end -------------------------------------------------------------------------------- /lib/vipergen/templatemanager.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | module Vipergen 3 | class TemplateManager 4 | 5 | # Returns the templates dir 6 | def self.templates_dir 7 | t = "#{Gem.dir}/gems/#{Vipergen::NAME}-#{Vipergen::VERSION}/lib/templates" 8 | end 9 | 10 | # Get the available templates paths 11 | # @return Array[String] with available templates paths 12 | def self.templates_paths() 13 | template_dir = Vipergen::TemplateManager.templates_dir 14 | return Vipergen::DirUtils.directories_in(template_dir) 15 | end 16 | 17 | # Get the templates names 18 | # @return Array[String] with templates names (got from the folder) 19 | def self.templates() 20 | templates_paths.map{|template_path| template_name_from_path(template_path)} 21 | end 22 | 23 | # Returns the template name from a given template_path 24 | # @return String with the template name 25 | def self.template_name_from_path(template_path) 26 | return template_path.split("/").last 27 | end 28 | 29 | # Returns the description of all the templates available 30 | # @return String with the entire description 31 | def self.templates_description() 32 | description = "\nAvailable templates \n" 33 | description += "------------------- \n" 34 | self.templates_paths.each do |template_path| 35 | description += "> #{template_description(template_path)} \n" 36 | end 37 | return description 38 | end 39 | 40 | # Returns the description of a given template 41 | # @param template String with the template path whose description is going to be returned 42 | # @return String with the template description 43 | def self.template_description(template_path) 44 | template_description = "" 45 | 46 | # Reading yaml 47 | template_content = YAML.load_file(File.join(template_path,'viperspec.yml')) 48 | 49 | # Generating string 50 | template_description+= "| #{template_name_from_path(template_path)} by #{template_content["author"]} |: #{template_content["template_description"]}" 51 | end 52 | end 53 | end -------------------------------------------------------------------------------- /lib/vipergen/version.rb: -------------------------------------------------------------------------------- 1 | module Vipergen 2 | NAME = "vipergen" 3 | VERSION = "0.2.1" 4 | end -------------------------------------------------------------------------------- /lib/vipergen/viperthor.rb: -------------------------------------------------------------------------------- 1 | require 'thor' 2 | require 'vipergen' 3 | 4 | module Vipergen 5 | class ViperThor < Thor 6 | desc "generate", "Generate a VIPER module" 7 | option :language, :required => false, :default => 'objc', :type => :string, :desc => "The language of the generated module (swift, objc)" 8 | option :template, :required => false, :default => 'default', :type => :string , :desc => "Template for the generation" 9 | option :path, :required => true, :type => :string , :desc => "Path where the output module is going to be saved" 10 | def generate(name) 11 | Vipergen::Generator.generate_viper(options[:template], options[:language], name, options[:path]) 12 | end 13 | 14 | desc "templates", "Get a list of available templates" 15 | def templates() 16 | puts Vipergen::TemplateManager.templates_description() 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | 3 | require 'rubygems' 4 | require "bundler/gem_tasks" 5 | require "rspec/core/rake_task" 6 | require "vipergen" 7 | 8 | RSpec::Core::RakeTask.new 9 | 10 | task :default => [:spec] 11 | task :test => :spec 12 | task :debug do 13 | Vipergen::Generator.generate_viper('default','objc','Debug','~/Desktop') 14 | end -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/11030946903_6579e3c9a1_o-106.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/11030946903_6579e3c9a1_o-106.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/11030946903_6579e3c9a1_o-small-107.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/11030946903_6579e3c9a1_o-small-107.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/PresetImageFill0-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/PresetImageFill0-1.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/PresetImageFill1-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/PresetImageFill1-2.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/PresetImageFill2-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/PresetImageFill2-3.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/PresetImageFill3-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/PresetImageFill3-4.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/PresetImageFill4-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/PresetImageFill4-5.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/PresetImageFill5-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/PresetImageFill5-6.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/image00-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/image00-9.png -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/image00-small-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/image00-small-10.png -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/image02-18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/image02-18.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/image02-small-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/image02-small-19.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/mt0@2x-20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/mt0@2x-20.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/mt1@2x-21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/mt1@2x-21.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/mt2@2x-22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/mt2@2x-22.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/mt4@2x-23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/mt4@2x-23.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/mt5@2x-24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/mt5@2x-24.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/mt6@2x-25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/mt6@2x-25.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/pasted-image-49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/pasted-image-49.png -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/st0-150.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/st0-150.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/st1-27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/st1-27.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/st2-28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/st2-28.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/st3-29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/st3-29.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/st4-30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/st4-30.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Data/st5-31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Data/st5-31.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Index.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Index.zip -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Metadata/BuildVersionHistory.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pptx 6 | M6.2.2-1878-1 7 | M6.2-1861-1 8 | 9 | 10 | -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Metadata/DocumentIdentifier: -------------------------------------------------------------------------------- 1 | EE19BB44-B369-46FE-B6E2-34B35170B68F -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/Metadata/Properties.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/Metadata/Properties.plist -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/preview-micro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/preview-micro.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/preview-web.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/preview-web.jpg -------------------------------------------------------------------------------- /slides/viper_slides_codemotion.key/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redbooth/viper-module-generator/10ea3e718733505ca32c764ed8be038f98f564dc/slides/viper_slides_codemotion.key/preview.jpg -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'vipergen' 2 | require "codeclimate-test-reporter" 3 | 4 | CodeClimate::TestReporter.start 5 | -------------------------------------------------------------------------------- /spec/vipergen/vipergen_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Vipergen do 4 | context "when generating path" do 5 | it "should return nil if no valid template" do 6 | valid_template = Vipergen::FileManager.is_template_valid("asdgas") 7 | expect(valid_template).to be(false) 8 | end 9 | it "should return nil if no valid language" do 10 | valid_template = Vipergen::FileManager.is_template_valid("asdgas") 11 | expect(valid_template).to be(false) 12 | end 13 | it "should return nil if no valid language when getting path" do 14 | path = Vipergen::FileManager.path_from("default", "asgass") 15 | expect(path).to be(nil) 16 | end 17 | it "should return nil if no valid template when getting path" do 18 | path = Vipergen::FileManager.path_from("asga", "swift") 19 | expect(path).to be(nil) 20 | end 21 | it "should append the name to the given user path" do 22 | to_path = Vipergen::FileManager.destination_viper_path("path/", "pepito") 23 | expect(to_path).to eq(File.join(File.expand_path("path/"),"pepito")) 24 | end 25 | end 26 | context "copying a folder to a diferent place" do 27 | before (:each) do 28 | Dir.mkdir 'foo' 29 | Dir.mkdir 'foo/subfoo' 30 | end 31 | 32 | it "should copy a given folder properly" do 33 | Vipergen::FileManager.copy('foo','test_foo') 34 | expect(File.directory?('test_foo/subfoo')).to eq(true) 35 | end 36 | 37 | after (:each) do 38 | FileUtils.rm_rf('foo') 39 | FileUtils.rm_rf('test_foo') 40 | end 41 | end 42 | end 43 | 44 | describe Vipergen::Generator do 45 | context "when renaming file content" do 46 | before (:each) do 47 | File.open("test.txt", 'w') {|f| f.write("I'm a #{Vipergen::Generator::REPLACEMENT_KEY} file") } 48 | end 49 | 50 | it "should rename every VIPER word to the given name" do 51 | Vipergen::Generator.rename_file_content("test.txt","RENAMED") 52 | file = File.open("test.txt", "rb") 53 | content = file.read 54 | expect(content).to eq("I'm a RENAMED file") 55 | end 56 | 57 | after (:each) do 58 | FileUtils.rm('test.txt') 59 | end 60 | end 61 | 62 | context "when renaming file" do 63 | before (:each) do 64 | File.open("#{Vipergen::Generator::REPLACEMENT_KEY}test.txt", 'w') {|f| f.write("I'm a #{Vipergen::Generator::REPLACEMENT_KEY} file") } 65 | end 66 | 67 | it "every file should be renamed in rename_files" do 68 | expect(Vipergen::Generator).to receive(:rename_file) 69 | Vipergen::Generator.rename_files(["#{Vipergen::Generator::REPLACEMENT_KEY}file.txt"], "pepito") 70 | end 71 | 72 | it "should raise a SyntaxError exeption if there's a file in the template without the proper name" do 73 | expect{Vipergen::Generator.rename_files(["asgasgs.txt"], "pepito")}.to raise_error 74 | end 75 | 76 | it "should rename the VIPER in name to the given name" do 77 | file = "#{Vipergen::Generator::REPLACEMENT_KEY}test.txt" 78 | name = "RENAMED" 79 | Vipergen::Generator.rename_file(file, name) 80 | expect(File.exist? "RENAMEDtest.txt").to eq(true) 81 | end 82 | 83 | it "should rename the file content after the file name rename" do 84 | file = "#{Vipergen::Generator::REPLACEMENT_KEY}test.txt" 85 | name = "RENAMED" 86 | expect(Vipergen::Generator).to receive(:rename_file_content) 87 | Vipergen::Generator.rename_file(file, name) 88 | end 89 | 90 | after (:each) do 91 | File.delete "#{Vipergen::Generator::REPLACEMENT_KEY}test.txt" if File.exist? "#{Vipergen::Generator::REPLACEMENT_KEY}test.txt" 92 | File.delete "RENAMEDtest.txt" if File.exist? "RENAMEDtest.txt" 93 | end 94 | end 95 | end 96 | 97 | describe Vipergen::DirUtils do 98 | context "getting directories" do 99 | before (:each) do 100 | Dir.mkdir 'foo' 101 | Dir.mkdir 'foo/subfoo' 102 | end 103 | 104 | it "should return the directories inside a given one" do 105 | expect(Vipergen::DirUtils.directories_in('foo').count).to eq(1) 106 | end 107 | 108 | after (:each) do 109 | FileUtils.rm_rf('foo') 110 | end 111 | end 112 | end 113 | 114 | describe Vipergen::TemplateManager do 115 | context "getting templates" do 116 | before (:each) do 117 | Dir.mkdir 'foo' 118 | Dir.mkdir 'foo/subfoo' 119 | Dir.mkdir 'foo/subfoo2' 120 | end 121 | 122 | it "should return the proper templates in templates directory" do 123 | Vipergen::TemplateManager.stub(:templates_dir).and_return('foo/') 124 | expect(Vipergen::TemplateManager.templates_paths.count).to eq(2) 125 | end 126 | 127 | after (:each) do 128 | FileUtils.rm_rf('foo') 129 | end 130 | end 131 | end 132 | -------------------------------------------------------------------------------- /vipergen.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path('../lib', __FILE__) 3 | require 'vipergen/version' 4 | 5 | Gem::Specification.new do |s| 6 | s.name = 'vipergen' 7 | s.version = Vipergen::VERSION.dup 8 | s.platform = Gem::Platform::RUBY 9 | s.summary = 'Generates XCode VIPER module controllers structure' 10 | s.email = 'pedro@redbooth.com' 11 | s.homepage = 'http://github.com/teambox/viper-module-generator' 12 | s.description = 'Based on the objc.io post about VIPER. It saves time in the implementation generating the controllers and adding interactions between them (in Swift or Objective-C)' 13 | s.authors = ['Pedro Piñera'] 14 | s.license = 'MIT' 15 | 16 | # Files 17 | s.files = Dir['LICENSE', 'README.md', 'lib/**/*'] 18 | s.test_files = Dir['spec/**/*.rb'] 19 | s.require_path = 'lib' 20 | 21 | # Dependencies 22 | s.add_development_dependency 'rake' 23 | s.add_development_dependency 'rspec' 24 | s.add_development_dependency 'bundler', '~> 1.0' 25 | s.add_development_dependency 'byebug' 26 | s.add_dependency 'thor' 27 | 28 | # Executables 29 | s.executables << 'vipergen' 30 | s.bindir = 'bin' 31 | 32 | # Documentation 33 | s.rdoc_options = ['--charset=UTF-8'] 34 | s.extra_rdoc_files = [ 35 | 'README.md' 36 | ] 37 | 38 | end --------------------------------------------------------------------------------