├── .circleci └── config.yml ├── .gitignore ├── CONTRIBUTING ├── LICENSE ├── README.md ├── android ├── build.gradle ├── lint.xml └── src │ ├── debug │ └── res │ │ └── xml │ │ └── network_security_config.xml │ ├── main │ ├── AndroidManifest.xml │ ├── kotlin │ │ └── org │ │ │ └── example │ │ │ └── kotlin │ │ │ └── multiplatform │ │ │ └── app │ │ │ ├── ExampleApplication.kt │ │ │ └── HelloActivity.kt │ └── res │ │ ├── layout │ │ └── activity_hello.xml │ │ └── values │ │ ├── strings.xml │ │ └── styles.xml │ ├── release │ └── res │ │ └── xml │ │ └── network_security_config.xml │ └── test │ └── kotlin │ └── GreenTestForCISetup.kt ├── build.gradle ├── buildSrc ├── build.gradle └── src │ └── main │ └── java │ └── Dependencies.kt ├── common ├── build.gradle ├── common.podspec └── src │ ├── commonDebug │ └── kotlin │ │ └── org │ │ └── example │ │ └── kotlin │ │ └── multiplatform │ │ └── data │ │ └── defaultNetworkConfig.kt │ ├── commonMain │ └── kotlin │ │ └── org │ │ └── example │ │ └── kotlin │ │ └── multiplatform │ │ ├── api │ │ └── Api.kt │ │ ├── coroutines │ │ └── CustomMainScope.kt │ │ ├── data │ │ ├── NetworkDataSource.kt │ │ ├── model │ │ │ └── Greeting.kt │ │ └── responses │ │ │ ├── ErrorResponse.kt │ │ │ └── HelloResponse.kt │ │ ├── di │ │ └── NotDagger.kt │ │ ├── presenter │ │ └── HelloPresenter.kt │ │ ├── repository │ │ ├── NetworkRepository.kt │ │ └── model │ │ │ └── Greeting.kt │ │ └── usecase │ │ └── GetHello.kt │ ├── commonRelease │ └── kotlin │ │ └── org │ │ └── example │ │ └── kotlin │ │ └── multiplatform │ │ └── data │ │ └── defaultNetworkConfig.kt │ ├── iOSMain │ └── kotlin │ │ └── org │ │ └── example │ │ └── kotlin │ │ └── multiplatform │ │ ├── coroutines │ │ └── CustomMainScope.kt │ │ └── presenter │ │ └── currentPlatform.kt │ └── jvmMain │ └── kotlin │ └── org │ └── example │ └── kotlin │ └── multiplatform │ ├── coroutines │ └── CustomMainScope.kt │ └── presenter │ └── currentPlatform.kt ├── detekt.yml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── ios ├── .bundle │ └── config ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── KotlinMultiplatformTemplate.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── KotlinMultiplatformTemplate.xcscheme ├── KotlinMultiplatformTemplate.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── KotlinMultiplatformTemplate │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── MainViewController.swift ├── KotlinMultiplatformTemplateTests │ ├── Info.plist │ └── KotlinMultiplatformProjectTests.swift ├── KotlinMultiplatformTemplateUITests │ ├── Info.plist │ └── KotlinMultiplatformTemplateUITests.swift ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── common.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ └── Target Support Files │ │ ├── Pods-KotlinMultiplatformTemplate │ │ ├── Pods-KotlinMultiplatformTemplate-acknowledgements.markdown │ │ ├── Pods-KotlinMultiplatformTemplate-acknowledgements.plist │ │ ├── Pods-KotlinMultiplatformTemplate-dummy.m │ │ ├── Pods-KotlinMultiplatformTemplate.debug.xcconfig │ │ └── Pods-KotlinMultiplatformTemplate.release.xcconfig │ │ └── common │ │ └── common.xcconfig └── fastlane │ ├── Appfile │ └── Fastfile ├── settings.gradle └── web └── webpack.config.d ├── .gitignore └── bundle.js /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | defaults: &defaults 2 | working_directory: ~/code 3 | docker: 4 | - image: circleci/openjdk:8-jdk 5 | environment: 6 | JVM_OPTS: -Xmx3200m 7 | GRADLE_OPTS: '-Dorg.gradle.daemon=false' 8 | _JAVA_OPTIONS: "-Xms256m -Xmx1280m -XX:MaxPermSize=350m" 9 | 10 | version: 2 11 | jobs: 12 | lint: 13 | <<: *defaults 14 | steps: 15 | - checkout 16 | - restore_cache: 17 | key: jars--{{ checksum "build.gradle" }} 18 | - run: 19 | name: Lint project 20 | command: ./gradlew -Porg.gradle.project.buildAndroid=false detekt 21 | - save_cache: 22 | paths: 23 | - ~/.gradle 24 | key: jars--{{ checksum "build.gradle" }} 25 | - run: 26 | name: Save detekt results 27 | command: | 28 | mkdir -p ~/detekt/ 29 | find . -type f -regex ".*/build/reports/detekt/*" -exec cp {} ~/detekt/ \; 30 | when: always 31 | - store_test_results: 32 | path: ~/detekt 33 | - store_artifacts: 34 | path: ~/detekt 35 | 36 | build-android: 37 | <<: *defaults 38 | docker: 39 | - image: circleci/android:api-29 40 | steps: 41 | - checkout 42 | - restore_cache: 43 | key: jars-{{ checksum "build.gradle" }}-{{ checksum "android/build.gradle" }} 44 | - run: 45 | name: Run checks 46 | command: ./gradlew -Porg.gradle.project.buildAndroid=true :android:testDebugUnitTest :android:detekt :android:lintDebug 47 | - run: 48 | name: Build Application 49 | command: ./gradlew -Porg.gradle.project.buildAndroid=true :android:assemble 50 | - save_cache: 51 | paths: 52 | - ~/.gradle 53 | key: jars-{{ checksum "build.gradle" }}-{{ checksum "android/build.gradle" }} 54 | - store_artifacts: 55 | path: android/build/outputs/apk 56 | destination: apk 57 | - store_artifacts: 58 | path: android/build/reports 59 | destination: reports 60 | - store_test_results: 61 | path: android/build/test-results 62 | 63 | build-ios: 64 | macos: 65 | xcode: "11.5.0" 66 | environment: 67 | FL_OUTPUT_DIR: output 68 | FASTLANE_LANE: tests 69 | shell: /bin/bash --login -o pipefail 70 | steps: 71 | - checkout 72 | - run: 73 | name: Set Ruby Version 74 | command: echo "ruby-2.5" > ~/.ruby-version 75 | - restore_cache: 76 | key: gems-{{ checksum "ios/Gemfile.lock" }} 77 | - run: 78 | name: Configure Bundler 79 | command: sudo gem install bundler -v "$(grep -A 1 "BUNDLED WITH" ios/Gemfile.lock | tail -n 1)" 80 | - run: 81 | name: Run Bundler 82 | command: cd ios && bundle check || bundle install 83 | - save_cache: 84 | key: gems-{{ checksum "ios/Gemfile.lock" }} 85 | paths: 86 | - ios/vendor/bundle 87 | - restore_cache: 88 | key: pods-{{ checksum "ios/Podfile.lock" }} 89 | - run: 90 | name: Pod install 91 | command: cd ios && bundle exec pod install 92 | - save_cache: 93 | key: pods-{{ checksum "ios/Podfile.lock" }} 94 | paths: 95 | - ios/Pods 96 | - restore_cache: 97 | key: gradle-{{ checksum "build.gradle" }}-{{ checksum "common/build.gradle" }} 98 | - run: 99 | name: fastlane 100 | command: cd ios && bundle exec fastlane ios $FASTLANE_LANE --verbose 101 | - save_cache: 102 | paths: 103 | - ~/.gradle 104 | key: gradle-{{ checksum "build.gradle" }}-{{ checksum "common/build.gradle" }} 105 | - store_artifacts: 106 | path: ios/output/ 107 | - store_test_results: 108 | path: ios/output/scan 109 | swiftlint: 110 | docker: 111 | - image: dantoml/swiftlint:latest 112 | steps: 113 | - checkout 114 | - run: swiftlint lint --reporter junit | tee result.xml 115 | - store_artifacts: 116 | path: result.xml 117 | - store_test_results: 118 | path: result.xml 119 | 120 | workflows: 121 | version: 2 122 | pr-checks: 123 | jobs: 124 | - lint 125 | # - swiftlint 126 | - build-android 127 | - build-ios 128 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/web,node,java,kotlin,android,intellij,visualstudiocode,ios,fastlane,macos 3 | # Edit at https://www.gitignore.io/?templates=web,node,java,kotlin,android,intellij,visualstudiocode,ios,fastlane,macos 4 | 5 | ### Android ### 6 | # Built application files 7 | *.apk 8 | *.ap_ 9 | *.aab 10 | 11 | # Files for the ART/Dalvik VM 12 | *.dex 13 | 14 | # Java class files 15 | *.class 16 | 17 | # Generated files 18 | bin/ 19 | gen/ 20 | out/ 21 | 22 | # Gradle files 23 | .gradle/ 24 | build/ 25 | 26 | # Local configuration file (sdk path, etc) 27 | local.properties 28 | 29 | # Proguard folder generated by Eclipse 30 | proguard/ 31 | 32 | # Log Files 33 | *.log 34 | 35 | # Android Studio Navigation editor temp files 36 | .navigation/ 37 | 38 | # Android Studio captures folder 39 | captures/ 40 | 41 | # IntelliJ 42 | *.iml 43 | .idea/ 44 | 45 | # Keystore files 46 | # Uncomment the following lines if you do not want to check your keystore files in. 47 | *.jks 48 | *.keystore 49 | 50 | # External native build folder generated in Android Studio 2.2 and later 51 | .externalNativeBuild 52 | 53 | # Google Services (e.g. APIs or Firebase) 54 | google-services.json 55 | 56 | # Freeline 57 | freeline.py 58 | freeline/ 59 | freeline_project_description.json 60 | 61 | # fastlane 62 | */fastlane/report.xml 63 | */fastlane/Preview.html 64 | */fastlane/screenshots 65 | */fastlane/test_output 66 | */fastlane/README.md 67 | 68 | # Version control 69 | vcs.xml 70 | 71 | # lint 72 | */lint/intermediates/ 73 | */lint/generated/ 74 | */lint/outputs/ 75 | */lint/tmp/ 76 | */lint/reports/ 77 | 78 | ### Android Patch ### 79 | gen-external-apklibs 80 | output.json 81 | 82 | ### fastlane ### 83 | # fastlane - A streamlined workflow tool for Cocoa deployment 84 | # 85 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 86 | # screenshots whenever they are needed. 87 | # For more information about the recommended setup visit: 88 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 89 | 90 | # fastlane specific 91 | 92 | # deliver temporary files 93 | 94 | # snapshot generated screenshots 95 | */fastlane/screenshots/**/*.png 96 | */fastlane/screenshots/screenshots.html 97 | 98 | # scan temporary files 99 | 100 | ### Intellij ### 101 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 102 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 103 | 104 | # User-specific stuff 105 | .idea/**/workspace.xml 106 | .idea/**/tasks.xml 107 | .idea/**/usage.statistics.xml 108 | .idea/**/dictionaries 109 | .idea/**/shelf 110 | 111 | # Generated files 112 | .idea/**/contentModel.xml 113 | 114 | # Sensitive or high-churn files 115 | .idea/**/dataSources/ 116 | .idea/**/dataSources.ids 117 | .idea/**/dataSources.local.xml 118 | .idea/**/sqlDataSources.xml 119 | .idea/**/dynamic.xml 120 | .idea/**/uiDesigner.xml 121 | .idea/**/dbnavigator.xml 122 | 123 | # Gradle 124 | .idea/**/gradle.xml 125 | .idea/**/libraries 126 | 127 | # Gradle and Maven with auto-import 128 | # When using Gradle or Maven with auto-import, you should exclude module files, 129 | # since they will be recreated, and may cause churn. Uncomment if using 130 | # auto-import. 131 | .idea/modules.xml 132 | .idea/*.iml 133 | .idea/modules 134 | *.iml 135 | *.ipr 136 | 137 | # CMake 138 | cmake-build-*/ 139 | 140 | # Mongo Explorer plugin 141 | .idea/**/mongoSettings.xml 142 | 143 | # File-based project format 144 | *.iws 145 | 146 | # IntelliJ 147 | 148 | # mpeltonen/sbt-idea plugin 149 | .idea_modules/ 150 | 151 | # JIRA plugin 152 | atlassian-ide-plugin.xml 153 | 154 | # Cursive Clojure plugin 155 | .idea/replstate.xml 156 | 157 | # Crashlytics plugin (for Android Studio and IntelliJ) 158 | com_crashlytics_export_strings.xml 159 | crashlytics.properties 160 | crashlytics-build.properties 161 | fabric.properties 162 | 163 | # Editor-based Rest Client 164 | .idea/httpRequests 165 | 166 | # Android studio 3.1+ serialized cache file 167 | .idea/caches/build_file_checksums.ser 168 | 169 | ### Intellij Patch ### 170 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 171 | 172 | # *.iml 173 | # modules.xml 174 | # .idea/misc.xml 175 | # *.ipr 176 | 177 | # Sonarlint plugin 178 | .idea/sonarlint 179 | 180 | #!! ERROR: ios is undefined. Use list command to see defined gitignore types !!# 181 | 182 | ### Java ### 183 | # Compiled class file 184 | 185 | # Log file 186 | 187 | # BlueJ files 188 | *.ctxt 189 | 190 | # Mobile Tools for Java (J2ME) 191 | .mtj.tmp/ 192 | 193 | # Package Files # 194 | #*.jar 195 | *.war 196 | *.nar 197 | *.ear 198 | *.zip 199 | *.tar.gz 200 | *.rar 201 | 202 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 203 | hs_err_pid* 204 | 205 | ### Kotlin ### 206 | # Compiled class file 207 | 208 | # Log file 209 | 210 | # BlueJ files 211 | 212 | # Mobile Tools for Java (J2ME) 213 | 214 | # Package Files # 215 | 216 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 217 | 218 | ### macOS ### 219 | # General 220 | .DS_Store 221 | .AppleDouble 222 | .LSOverride 223 | 224 | # Icon must end with two \r 225 | Icon 226 | 227 | # Thumbnails 228 | ._* 229 | 230 | # Files that might appear in the root of a volume 231 | .DocumentRevisions-V100 232 | .fseventsd 233 | .Spotlight-V100 234 | .TemporaryItems 235 | .Trashes 236 | .VolumeIcon.icns 237 | .com.apple.timemachine.donotpresent 238 | 239 | # Directories potentially created on remote AFP share 240 | .AppleDB 241 | .AppleDesktop 242 | Network Trash Folder 243 | Temporary Items 244 | .apdisk 245 | 246 | ### Node ### 247 | # Logs 248 | logs 249 | npm-debug.log* 250 | yarn-debug.log* 251 | yarn-error.log* 252 | lerna-debug.log* 253 | 254 | # Diagnostic reports (https://nodejs.org/api/report.html) 255 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 256 | 257 | # Runtime data 258 | pids 259 | *.pid 260 | *.seed 261 | *.pid.lock 262 | 263 | # Directory for instrumented libs generated by jscoverage/JSCover 264 | lib-cov 265 | 266 | # Coverage directory used by tools like istanbul 267 | coverage 268 | *.lcov 269 | 270 | # nyc test coverage 271 | .nyc_output 272 | 273 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 274 | .grunt 275 | 276 | # Bower dependency directory (https://bower.io/) 277 | bower_components 278 | 279 | # node-waf configuration 280 | .lock-wscript 281 | 282 | # Compiled binary addons (https://nodejs.org/api/addons.html) 283 | build/Release 284 | 285 | # Dependency directories 286 | node_modules/ 287 | jspm_packages/ 288 | 289 | # TypeScript v1 declaration files 290 | typings/ 291 | 292 | # TypeScript cache 293 | *.tsbuildinfo 294 | 295 | # Optional npm cache directory 296 | .npm 297 | 298 | # Optional eslint cache 299 | .eslintcache 300 | 301 | # Optional REPL history 302 | .node_repl_history 303 | 304 | # Output of 'npm pack' 305 | *.tgz 306 | 307 | # Yarn Integrity file 308 | .yarn-integrity 309 | 310 | # dotenv environment variables file 311 | .env 312 | .env.test 313 | 314 | # parcel-bundler cache (https://parceljs.org/) 315 | .cache 316 | 317 | # next.js build output 318 | .next 319 | 320 | # nuxt.js build output 321 | .nuxt 322 | 323 | # vuepress build output 324 | .vuepress/dist 325 | 326 | # Serverless directories 327 | .serverless/ 328 | 329 | # FuseBox cache 330 | .fusebox/ 331 | 332 | # DynamoDB Local files 333 | .dynamodb/ 334 | 335 | ### VisualStudioCode ### 336 | .vscode/* 337 | !.vscode/settings.json 338 | !.vscode/tasks.json 339 | !.vscode/launch.json 340 | !.vscode/extensions.json 341 | 342 | ### VisualStudioCode Patch ### 343 | # Ignore all local history of files 344 | .history 345 | 346 | # End of https://www.gitignore.io/api/web,node,java,kotlin,android,intellij,visualstudiocode,ios,fastlane 347 | -------------------------------------------------------------------------------- /CONTRIBUTING: -------------------------------------------------------------------------------- 1 | If you would like to contribute code to this repository you can do so through GitHub by creating a new branch in the repository and sending a pull request or opening an issue. Please, remember that there are some requirements you have to pass before accepting your contribution: 2 | 3 | * Write clean code and test it. 4 | * The code written will have to match the product owner requirements. 5 | * Follow the repository code style. 6 | * Write good commit messages. 7 | * Do not send pull requests without checking if the project build is OK in the CI environment. 8 | * Review if your changes affects the repository documentation and update it. 9 | * Describe the PR content and don't hesitate to add comments to explain us why you've added or changed something. 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CircleCI Badge](https://circleci.com/gh/wiyarmir/kotlin-multiplatform-mobile-template.svg?style=svg)](https://circleci.com/gh/wiyarmir/kotlin-multiplatform-mobile-template) 2 | ![Kotlin Version](https://img.shields.io/badge/kotlin-v1.4.0-F88909?style=flat&logo=kotlin) 3 | 4 | # Kotlin Multiplatform Mobile Template 5 | 6 | Template that will give you a ready-to-go project including: 7 | 8 | - Android App project with KotlinJVM at [android/](/android) 9 | - iOS App project with KotlinNative at [ios/](/ios) 10 | - Shared network, domain and presentation at [common/](/common) 11 | 12 | *Looking for a project with Backend and Web as well? It's here: https://github.com/wiyarmir/kotlin-multiplatform-template* 13 | 14 | *Looking for a project with just Backend and Web? It's here: https://github.com/wiyarmir/kotlin-multiplatform-frontend-template* 15 | 16 | ## Building and running the project 17 | 18 | ### Android 19 | 20 | Open the root project in Android Studio or IntelliJ, and it will recognise the Android App configuration after a 21 | successful Gradle sync. You can use that configuration to run, debug and profile the app. 22 | 23 | ### iOS 24 | 25 | Open the workspace located at [ios/KotlinMultiplatformTemplate.xcworkspace](/ios/KotlinMultiplatformTemplate.xcworkspace) 26 | in XCode. The Podfile includes an entry to the common code with an extra user script for it to be recompiled as a build 27 | step. 28 | 29 | ## Contributing 30 | 31 | If you would like to contribute code to this repository you can do so through GitHub by creating a new branch in the repository and sending a pull request or opening an issue. Please, remember that there are some requirements you have to pass before accepting your contribution: 32 | 33 | * Write clean code and test it. 34 | * The code written will have to match the product owner requirements. 35 | * Follow the repository code style. 36 | * Write good commit messages. 37 | * Do not send pull requests without checking if the project build is OK in the CI environment. 38 | * Review if your changes affects the repository documentation and update it. 39 | * Describe the PR content and don't hesitate to add comments to explain us why you've added or changed something. 40 | 41 | ## License 42 | 43 | Copyright 2019 Kotlin Multiplatform Template 44 | 45 | Licensed under the Apache License, Version 2.0 (the "License"); you may 46 | not use this file except in compliance with the License. You may obtain a 47 | copy of the License at 48 | 49 | http://www.apache.org/licenses/LICENSE-2.0 50 | 51 | Unless required by applicable law or agreed to in writing, software 52 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 53 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 54 | License for the specific language governing permissions and limitations 55 | under the License. 56 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "kotlin-multiplatform" 2 | apply plugin: "com.android.application" 3 | 4 | android { 5 | compileSdkVersion 28 6 | 7 | defaultConfig { 8 | applicationId "org.example.kotlin.multiplatform.app" 9 | minSdkVersion 21 10 | targetSdkVersion 28 11 | versionCode 1 12 | versionName "0.0.1" 13 | } 14 | 15 | signingConfigs {} 16 | 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | 24 | //This is for MultiplatformSettings 25 | debug { 26 | // MPP libraries don't currently get this resolution automatically 27 | matchingFallbacks = ['release'] 28 | } 29 | } 30 | 31 | packagingOptions { 32 | exclude "**/*.kotlin_module" 33 | } 34 | } 35 | 36 | kotlin { 37 | sourceSets { 38 | commonMain { 39 | dependencies { 40 | implementation project(':common') 41 | } 42 | } 43 | 44 | androidMain { 45 | dependencies { 46 | } 47 | } 48 | } 49 | 50 | android { 51 | 52 | } 53 | } 54 | 55 | repositories { 56 | google() 57 | mavenCentral() 58 | } 59 | 60 | dependencies { 61 | implementation Libs.appcompat 62 | implementation Libs.cardview 63 | implementation Libs.recyclerview 64 | implementation Libs.material 65 | implementation Libs.constraintlayout 66 | 67 | implementation Libs.kotlinStdlib 68 | 69 | implementation Libs.kotlinxCoroutinesAndroid 70 | 71 | implementation Libs.ktorClientAndroid 72 | 73 | testImplementation Libs.kotlinTest 74 | testImplementation Libs.kotlinTestJunit 75 | testImplementation Libs.junit 76 | testImplementation Libs.mockitoKotlin 77 | } 78 | -------------------------------------------------------------------------------- /android/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/src/debug/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10.0.2.2 5 | 6 | 7 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /android/src/main/kotlin/org/example/kotlin/multiplatform/app/ExampleApplication.kt: -------------------------------------------------------------------------------- 1 | package org.example.kotlin.multiplatform.app 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import org.example.kotlin.multiplatform.di.NotDagger 6 | 7 | class ExampleApplication : Application() { 8 | 9 | val notDagger = NotDagger() 10 | 11 | override fun onCreate() { 12 | super.onCreate() 13 | Thread.setDefaultUncaughtExceptionHandler { _, throwable -> 14 | println(throwable) 15 | throwable.printStackTrace() 16 | throwable?.cause?.printStackTrace() 17 | } 18 | } 19 | } 20 | 21 | val Context.exampleApplication 22 | get() = this.applicationContext as ExampleApplication 23 | -------------------------------------------------------------------------------- /android/src/main/kotlin/org/example/kotlin/multiplatform/app/HelloActivity.kt: -------------------------------------------------------------------------------- 1 | package org.example.kotlin.multiplatform.app 2 | 3 | import android.os.Bundle 4 | import android.widget.Button 5 | import android.widget.TextView 6 | import androidx.appcompat.app.AppCompatActivity 7 | import com.google.android.material.snackbar.Snackbar 8 | import org.example.kotlin.multiplatform.presenter.HelloPresenter 9 | import org.example.kotlin.multiplatform.presenter.HelloView 10 | import org.example.kotlin.multiplatform.repository.model.Greeting 11 | 12 | class HelloActivity : AppCompatActivity() { 13 | 14 | private val view: HelloView by lazy { 15 | object : HelloView { 16 | 17 | private val text: TextView = findViewById(R.id.text) 18 | private val button: Button = findViewById(R.id.button) 19 | 20 | init { 21 | button.setOnClickListener { 22 | presenter.loadGreeting() 23 | } 24 | } 25 | 26 | override fun showGreeting(greeting: Greeting) { 27 | text.text = greeting.message 28 | } 29 | 30 | override fun showLoading() { 31 | Snackbar.make(findViewById(R.id.rootView), "Loading", Snackbar.LENGTH_SHORT).show() 32 | } 33 | 34 | override fun showError(error: String) { 35 | Snackbar.make(findViewById(R.id.rootView), error, Snackbar.LENGTH_SHORT).show() 36 | } 37 | } 38 | } 39 | 40 | private lateinit var presenter: HelloPresenter 41 | 42 | override fun onCreate(savedInstanceState: Bundle?) { 43 | super.onCreate(savedInstanceState) 44 | setContentView(R.layout.activity_hello) 45 | presenter = exampleApplication.notDagger.helloPresenter(view) 46 | } 47 | 48 | override fun onDestroy() { 49 | presenter.destroy() 50 | super.onDestroy() 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_hello.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 |