├── .gitignore ├── .idea ├── .name ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── deploymentTargetDropDown.xml ├── jarRepositories.xml ├── misc.xml └── sqldelight │ └── common │ └── .sqldelight ├── LICENSE ├── README.md ├── androidApp ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── kurt │ │ └── jokes │ │ └── presentation │ │ ├── JokesApplication.kt │ │ ├── MainActivity.kt │ │ ├── MainViewModelFactory.kt │ │ └── screens │ │ └── JokesScreen.kt │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ ├── bottom_navigation_text_color.xml │ └── ic_launcher_background.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle.kts ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── iosApp ├── .gitignore ├── JokesApp.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── mppexample.xcscheme ├── JokesApp.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── JokesApp │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── ContentView.swift │ ├── Info.plist │ ├── JokesApp.swift │ ├── JokesView.swift │ ├── JokesViewModelWrapper.swift │ ├── ViewController.swift │ ├── extensions │ │ └── Ktor_ioCloseable+.swift │ └── utils │ │ └── ViewModelWrapper.swift ├── JokesAppTests │ ├── Info.plist │ └── mppexampleTests.swift ├── JokesAppUITests │ ├── Info.plist │ └── mppexampleUITests.swift ├── Podfile ├── Podfile.lock └── Pods │ ├── Local Podspecs │ ├── common.podspec.json │ └── shared.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ └── project.pbxproj │ └── Target Support Files │ ├── Pods-JokesApp-JokesAppUITests │ ├── Pods-JokesApp-JokesAppUITests-Info.plist │ ├── Pods-JokesApp-JokesAppUITests-acknowledgements.markdown │ ├── Pods-JokesApp-JokesAppUITests-acknowledgements.plist │ ├── Pods-JokesApp-JokesAppUITests-dummy.m │ ├── Pods-JokesApp-JokesAppUITests-umbrella.h │ ├── Pods-JokesApp-JokesAppUITests.debug.xcconfig │ ├── Pods-JokesApp-JokesAppUITests.modulemap │ └── Pods-JokesApp-JokesAppUITests.release.xcconfig │ ├── Pods-JokesApp │ ├── Pods-JokesApp-Info.plist │ ├── Pods-JokesApp-acknowledgements.markdown │ ├── Pods-JokesApp-acknowledgements.plist │ ├── Pods-JokesApp-dummy.m │ ├── Pods-JokesApp-umbrella.h │ ├── Pods-JokesApp.debug.xcconfig │ ├── Pods-JokesApp.modulemap │ └── Pods-JokesApp.release.xcconfig │ ├── Pods-JokesAppTests │ ├── Pods-JokesAppTests-Info.plist │ ├── Pods-JokesAppTests-acknowledgements.markdown │ ├── Pods-JokesAppTests-acknowledgements.plist │ ├── Pods-JokesAppTests-dummy.m │ ├── Pods-JokesAppTests-umbrella.h │ ├── Pods-JokesAppTests.debug.xcconfig │ ├── Pods-JokesAppTests.modulemap │ └── Pods-JokesAppTests.release.xcconfig │ └── shared │ ├── shared.debug.xcconfig │ └── shared.release.xcconfig ├── settings.gradle.kts └── shared ├── build.gradle.kts ├── shared.podspec └── src ├── androidMain └── kotlin │ └── com │ └── kurt │ └── jokes │ └── mobile │ ├── CommonAndroid.kt │ ├── data │ └── local │ │ └── JokesDatabaseDriver.kt │ └── presentation │ ├── base │ ├── BaseViewModel.kt │ └── Dispatchers.kt │ └── features │ └── jokes │ └── JokesViewModelFactory.kt ├── androidTest └── kotlin │ └── com │ └── kurt │ └── jokes │ └── mobile │ ├── CommonTest.kt │ ├── CommonTestCoroutineDispatcher.kt │ └── CoroutineTestRule.kt ├── commonMain ├── kotlin │ └── com │ │ └── kurt │ │ └── jokes │ │ └── mobile │ │ ├── Common.kt │ │ ├── ServiceLocator.kt │ │ ├── data │ │ ├── RealJokesRepository.kt │ │ ├── local │ │ │ ├── JokesDatabaseDriver.kt │ │ │ └── JokesLocalSource.kt │ │ └── remote │ │ │ └── JokesRemoteSource.kt │ │ ├── domain │ │ ├── entities │ │ │ └── Joke.kt │ │ └── repositories │ │ │ └── JokesRepository.kt │ │ └── presentation │ │ ├── base │ │ ├── BaseViewModel.kt │ │ └── Dispatchers.kt │ │ ├── features │ │ └── jokes │ │ │ └── JokesViewModel.kt │ │ ├── helpers │ │ └── FlowHelpers.kt │ │ └── models │ │ └── UiState.kt └── sqldelight │ └── com │ └── kurt │ └── jokes │ └── Joke.sq ├── commonTest └── kotlin │ └── com │ └── kurt │ └── jokes │ └── mobile │ ├── CommonTest.kt │ ├── CommonTestCoroutineDispatcher.kt │ ├── FakeJokesRepository.kt │ └── JokesViewModelTest.kt ├── iosMain └── kotlin │ └── com │ └── kurt │ └── jokes │ └── mobile │ ├── CommonIos.kt │ ├── data │ └── local │ │ └── JokesDatabaseDriver.kt │ └── presentation │ └── base │ ├── BaseViewModel.kt │ └── Dispatchers.kt ├── iosTest └── kotlin │ └── com │ └── kurt │ └── jokes │ └── mobile │ ├── CommonTest.kt │ └── CommonTestCoroutineDispatcher.kt └── main └── AndroidManifest.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | *.aab 5 | 6 | # Files for the ART/Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | out/ 16 | release/ 17 | 18 | # Gradle files 19 | .gradle/ 20 | build/ 21 | 22 | # Local configuration file (sdk path, etc) 23 | local.properties 24 | 25 | # Proguard folder generated by Eclipse 26 | proguard/ 27 | 28 | # Log Files 29 | *.log 30 | 31 | # Android Studio Navigation editor temp files 32 | .navigation/ 33 | 34 | # Android Studio captures folder 35 | captures/ 36 | 37 | # IntelliJ 38 | *.iml 39 | .idea/workspace.xml 40 | .idea/tasks.xml 41 | .idea/gradle.xml 42 | .idea/assetWizardSettings.xml 43 | .idea/dictionaries 44 | .idea/libraries 45 | # Android Studio 3 in .gitignore file. 46 | .idea/caches 47 | .idea/modules.xml 48 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 49 | .idea/navEditor.xml 50 | 51 | # Keystore files 52 | # Uncomment the following lines if you do not want to check your keystore files in. 53 | #*.jks 54 | #*.keystore 55 | 56 | # External native build folder generated in Android Studio 2.2 and later 57 | .externalNativeBuild 58 | 59 | # Google Services (e.g. APIs or Firebase) 60 | # google-services.json 61 | 62 | # Freeline 63 | freeline.py 64 | freeline/ 65 | freeline_project_description.json 66 | 67 | # fastlane 68 | fastlane/report.xml 69 | fastlane/Preview.html 70 | fastlane/screenshots 71 | fastlane/test_output 72 | fastlane/readme.md 73 | 74 | # Version control 75 | vcs.xml 76 | 77 | # lint 78 | lint/intermediates/ 79 | lint/generated/ 80 | lint/outputs/ 81 | lint/tmp/ 82 | # lint/reports/ 83 | 84 | **/.DS_Store -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | JokesKMM -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | xmlns:android 17 | 18 | ^$ 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | xmlns:.* 28 | 29 | ^$ 30 | 31 | 32 | BY_NAME 33 | 34 |
35 |
36 | 37 | 38 | 39 | .*:id 40 | 41 | http://schemas.android.com/apk/res/android 42 | 43 | 44 | 45 |
46 |
47 | 48 | 49 | 50 | .*:name 51 | 52 | http://schemas.android.com/apk/res/android 53 | 54 | 55 | 56 |
57 |
58 | 59 | 60 | 61 | name 62 | 63 | ^$ 64 | 65 | 66 | 67 |
68 |
69 | 70 | 71 | 72 | style 73 | 74 | ^$ 75 | 76 | 77 | 78 |
79 |
80 | 81 | 82 | 83 | .* 84 | 85 | ^$ 86 | 87 | 88 | BY_NAME 89 | 90 |
91 |
92 | 93 | 94 | 95 | .* 96 | 97 | http://schemas.android.com/apk/res/android 98 | 99 | 100 | ANDROID_ATTRIBUTE_ORDER 101 | 102 |
103 |
104 | 105 | 106 | 107 | .* 108 | 109 | .* 110 | 111 | 112 | BY_NAME 113 | 114 |
115 |
116 |
117 |
118 | 119 | 121 |
122 |
-------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | -------------------------------------------------------------------------------- /.idea/sqldelight/common/.sqldelight: -------------------------------------------------------------------------------- 1 | {"databases":[{"packageName":"com.kurt.jokes","compilationUnits":[{"name":"androidDebug","sourceFolders":[{"path":"src/androidDebug/sqldelight","dependency":false},{"path":"src/androidMain/sqldelight","dependency":false},{"path":"src/commonMain/sqldelight","dependency":false}]},{"name":"androidRelease","sourceFolders":[{"path":"src/androidMain/sqldelight","dependency":false},{"path":"src/androidRelease/sqldelight","dependency":false},{"path":"src/commonMain/sqldelight","dependency":false}]},{"name":"iosArm64Main","sourceFolders":[{"path":"src/commonMain/sqldelight","dependency":false},{"path":"src/iosArm64Main/sqldelight","dependency":false},{"path":"src/iosMain/sqldelight","dependency":false}]},{"name":"iosX64Main","sourceFolders":[{"path":"src/commonMain/sqldelight","dependency":false},{"path":"src/iosMain/sqldelight","dependency":false},{"path":"src/iosX64Main/sqldelight","dependency":false}]},{"name":"metadataCommonMain","sourceFolders":[]},{"name":"metadataIosMain","sourceFolders":[]},{"name":"metadataMain","sourceFolders":[{"path":"src/commonMain/sqldelight","dependency":false}]}],"outputDirectory":"build/generated/sqldelight/code/JokesDatabase","className":"JokesDatabase","dependencies":[],"dialectPreset":"SQLITE_3_18","deriveSchemaFromMigrations":false}]} -------------------------------------------------------------------------------- /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 | # Jokes App 2 | 3 | A Kotlin Multiplatform sample 4 | 5 | ## Multiplatform Project 6 | 7 | This is a Kotlin/Multiplatform project uses code sharing between Android and iOS. 8 | 9 | Both applications are fully native and only share the common logic between the platforms. 10 | 11 | **android** - contains the Android project 12 | 13 | **ios** - contains the iOS project 14 | 15 | **common** - contains the shared Kotlin code 16 | 17 | ## Android and Shared 18 | 19 | Use **Android Studio** and open the project on the root of this repository. Android Studio will be able to see the gradle modules both on the **android** and **shared** module. 20 | 21 | ## iOS 22 | 23 | Use **Xcode** and open the **ios** folder or use **JokesApp.xcworkspace**. The shared modules cannot be seen from this project. iOS gets the shared code through a framework which is exported from the Kotlin project. 24 | 25 | Unfortunately, modifying the shared code requires Android Studio or IntelliJ IDEA. 26 | 27 | 28 | ## Authors 29 | 30 | - Kurt Renzo Acosta - [kurt.r.acosta@gmail.com](mailto:kurt.r.acosta@gmail.com) 31 | -------------------------------------------------------------------------------- /androidApp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /androidApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.application") 3 | kotlin("android") 4 | } 5 | 6 | android { 7 | compileSdk = 30 8 | defaultConfig { 9 | applicationId ="com.kuuuurt.jokes" 10 | minSdk = 21 11 | targetSdk = 30 12 | versionCode = 1 13 | versionName = "1.0.0" 14 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 15 | } 16 | 17 | buildTypes { 18 | getByName("release") { 19 | isMinifyEnabled = false 20 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") 21 | } 22 | } 23 | 24 | compileOptions { 25 | sourceCompatibility = JavaVersion.VERSION_1_8 26 | targetCompatibility = JavaVersion.VERSION_1_8 27 | } 28 | 29 | buildFeatures { 30 | compose = true 31 | } 32 | 33 | composeOptions { 34 | kotlinCompilerExtensionVersion = "1.0.0-rc01" 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = "1.8" 39 | } 40 | 41 | packagingOptions { 42 | exclude("META-INF/*.kotlin_module") 43 | } 44 | } 45 | 46 | dependencies { 47 | implementation(project(":shared")) 48 | 49 | val kotlin: String by project 50 | val coroutines: String by project 51 | val navigationVersion = "2.2.0-rc04" 52 | 53 | // Compose 54 | val compose = "1.0.0-rc01" 55 | implementation("androidx.compose.ui:ui:$compose") 56 | implementation("androidx.compose.ui:ui-tooling:$compose") 57 | implementation("androidx.compose.foundation:foundation:$compose") 58 | implementation("androidx.compose.material:material:$compose") 59 | 60 | // Lifecycle 61 | implementation("androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha07") 62 | 63 | // Kotlin 64 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin") 65 | 66 | // AndroidX 67 | implementation("androidx.appcompat:appcompat:1.4.0-alpha03") 68 | implementation("androidx.activity:activity-compose:1.3.0-rc01") 69 | implementation("androidx.activity:activity-ktx:1.3.0-rc01") 70 | implementation("androidx.core:core-ktx:1.6.0") 71 | implementation("com.google.android.material:material:1.3.0") 72 | 73 | // Coroutines 74 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines") 75 | 76 | val ANDROIDX_TEST = "1.3.0" 77 | val ESPRESSO = "3.3.0" 78 | androidTestImplementation("androidx.test:core-ktx:${ANDROIDX_TEST}") 79 | androidTestImplementation("androidx.test:runner:${ANDROIDX_TEST}") 80 | androidTestImplementation("androidx.test:rules:${ANDROIDX_TEST}") 81 | androidTestImplementation("androidx.test.ext:junit-ktx:1.1.2") 82 | androidTestImplementation("androidx.test.espresso:espresso-core:$ESPRESSO") 83 | androidTestImplementation("com.schibsted.spain:barista:3.6.0") 84 | } -------------------------------------------------------------------------------- /androidApp/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in testbuild.gradleadle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /androidApp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /androidApp/src/main/java/com/kurt/jokes/presentation/JokesApplication.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.presentation 2 | 3 | import android.app.Application 4 | import com.kurt.jokes.mobile.data.local.JokesDatabaseDriver.context 5 | 6 | class JokesApplication : Application() { 7 | override fun onCreate() { 8 | super.onCreate() 9 | context = this 10 | } 11 | } -------------------------------------------------------------------------------- /androidApp/src/main/java/com/kurt/jokes/presentation/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.presentation 2 | 3 | import android.os.Bundle 4 | import androidx.activity.compose.setContent 5 | import androidx.appcompat.app.AppCompatActivity 6 | import androidx.compose.material.MaterialTheme 7 | import com.kurt.jokes.presentation.screens.JokesScreen 8 | 9 | class MainActivity : AppCompatActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | 13 | setContent { 14 | MaterialTheme { 15 | JokesScreen() 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /androidApp/src/main/java/com/kurt/jokes/presentation/MainViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.presentation 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.kurt.jokes.mobile.presentation.features.jokes.JokesViewModel 6 | 7 | class MainViewModelFactory : ViewModelProvider.Factory { 8 | @Suppress("UNCHECKED_CAST") 9 | override fun create(modelClass: Class): T = when { 10 | modelClass.isAssignableFrom(JokesViewModel::class.java) -> { 11 | JokesViewModel.create() 12 | } 13 | else -> throw IllegalArgumentException("Unknown ViewModel class") 14 | } as T 15 | } -------------------------------------------------------------------------------- /androidApp/src/main/java/com/kurt/jokes/presentation/screens/JokesScreen.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.presentation.screens 2 | 3 | import androidx.compose.foundation.clickable 4 | import androidx.compose.foundation.layout.* 5 | import androidx.compose.foundation.lazy.LazyColumn 6 | import androidx.compose.foundation.lazy.items 7 | import androidx.compose.material.CircularProgressIndicator 8 | import androidx.compose.material.Divider 9 | import androidx.compose.material.MaterialTheme 10 | import androidx.compose.material.Text 11 | import androidx.compose.runtime.Composable 12 | import androidx.compose.runtime.collectAsState 13 | import androidx.compose.runtime.mutableStateOf 14 | import androidx.compose.runtime.remember 15 | import androidx.compose.ui.Alignment 16 | import androidx.compose.ui.Modifier 17 | import androidx.compose.ui.unit.dp 18 | import androidx.lifecycle.viewmodel.compose.viewModel 19 | import com.kurt.jokes.mobile.domain.entities.Joke 20 | import com.kurt.jokes.mobile.presentation.features.jokes.JokesViewModel 21 | import com.kurt.jokes.mobile.presentation.models.UiState 22 | import com.kurt.jokes.presentation.MainViewModelFactory 23 | 24 | @Composable 25 | fun JokesScreen() { 26 | val viewModel = viewModel(factory = MainViewModelFactory()) 27 | val jokes = viewModel.jokes.collectAsState(listOf()) 28 | val getJokesState = viewModel.jokesState.collectAsState(UiState.Loading) 29 | 30 | if (getJokesState.value == UiState.Loading) { 31 | Box( 32 | modifier = Modifier.fillMaxSize(), 33 | contentAlignment = Alignment.Center 34 | ) { 35 | CircularProgressIndicator() 36 | } 37 | } else { 38 | LazyColumn(modifier = Modifier.fillMaxSize()) { 39 | items(jokes.value) { 40 | JokeItem(it) 41 | } 42 | } 43 | } 44 | } 45 | 46 | @Composable 47 | fun JokeItem(joke: Joke) { 48 | val isPunchlineVisible = remember { mutableStateOf(false) } 49 | Column( 50 | modifier = Modifier.clickable { isPunchlineVisible.value = !isPunchlineVisible.value } 51 | ) { 52 | Column( 53 | modifier = Modifier 54 | .fillMaxWidth() 55 | .padding(16.dp) 56 | ) { 57 | Text( 58 | joke.setup, 59 | style = MaterialTheme.typography.h6 60 | ) 61 | if (isPunchlineVisible.value) { 62 | Text(joke.punchline) 63 | } 64 | } 65 | Divider() 66 | } 67 | } -------------------------------------------------------------------------------- /androidApp/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /androidApp/src/main/res/drawable/bottom_navigation_text_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | -------------------------------------------------------------------------------- /androidApp/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | 36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 | 68 | 70 | 72 | 74 | 75 | -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /androidApp/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /androidApp/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Jokes 3 | 4 | -------------------------------------------------------------------------------- /androidApp/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | gradlePluginPortal() 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | val sqldelight: String by project 9 | val kotlin: String by project 10 | 11 | dependencies { 12 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin") 13 | classpath("com.android.tools.build:gradle:7.0.0-beta05") 14 | classpath("com.squareup.sqldelight:gradle-plugin:$sqldelight") 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | mavenCentral() 22 | } 23 | } 24 | 25 | tasks.register("clean", Delete::class) { 26 | delete(rootProject.buildDir) 27 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # JVM 2 | org.gradle.jvmargs=-Xmx1536m 3 | 4 | # Android 5 | android.useAndroidX=true 6 | android.enableJetifier=true 7 | 8 | # Kotlin 9 | kotlin.code.style=official 10 | kotlin.mpp.enableGranularSourceSetsMetadata=true 11 | xcodeproj=ios/JokesApp.xcworkspace 12 | 13 | # Versions 14 | kotlin=1.5.10 15 | ktor=1.6.1 16 | coroutines=1.5.0-native-mt 17 | sqldelight=1.5.0 18 | serialization=1.2.1 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuuuurt/jokes-app-multiplatform/d5ad5d8634faf0b14661f7c9b2a824677cafe738/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Apr 17 18:08:21 PST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /iosApp/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/xcode,swift 2 | # Edit at https://www.gitignore.io/?templates=xcode,swift 3 | 4 | ### Swift ### 5 | # Xcode 6 | # 7 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 8 | 9 | ## Build generated 10 | build/ 11 | DerivedData/ 12 | 13 | ## Various settings 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata/ 23 | 24 | ## Other 25 | *.moved-aside 26 | *.xccheckout 27 | *.xcscmblueprint 28 | 29 | ## Obj-C/Swift specific 30 | *.hmap 31 | *.ipa 32 | *.dSYM.zip 33 | *.dSYM 34 | 35 | ## Playgrounds 36 | timeline.xctimeline 37 | playground.xcworkspace 38 | 39 | # Swift Package Manager 40 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 41 | # Packages/ 42 | # Package.pins 43 | # Package.resolved 44 | .build/ 45 | 46 | # CocoaPods 47 | # We recommend against adding the Pods directory to your .gitignore. However 48 | # you should judge for yourself, the pros and cons are mentioned at: 49 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 50 | # Pods/ 51 | # Add this line if you want to avoid checking in source code from the Xcode workspace 52 | # *.xcworkspace 53 | 54 | # Carthage 55 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 56 | # Carthage/Checkouts 57 | 58 | Carthage/Build 59 | 60 | # Accio dependency management 61 | Dependencies/ 62 | .accio/ 63 | 64 | # fastlane 65 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 66 | # screenshots whenever they are needed. 67 | # For more information about the recommended setup visit: 68 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 69 | 70 | fastlane/report.xml 71 | fastlane/Preview.html 72 | fastlane/screenshots/**/*.png 73 | fastlane/test_output 74 | 75 | # Code Injection 76 | # After new code Injection tools there's a generated folder /iOSInjectionProject 77 | # https://github.com/johnno1962/injectionforxcode 78 | 79 | iOSInjectionProject/ 80 | 81 | ### Xcode ### 82 | # Xcode 83 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 84 | 85 | ## User settings 86 | 87 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 88 | 89 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 90 | 91 | ## Xcode Patch 92 | *.xcodeproj/* 93 | !*.xcodeproj/project.pbxproj 94 | !*.xcodeproj/xcshareddata/ 95 | !*.xcworkspace/contents.xcworkspacedata 96 | /*.gcno 97 | 98 | ### Xcode Patch ### 99 | **/xcshareddata/WorkspaceSettings.xcsettings 100 | 101 | # End of https://www.gitignore.io/api/xcode,swift -------------------------------------------------------------------------------- /iosApp/JokesApp.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0BF61F917C389A38B94C302B /* Pods_JokesApp_JokesAppUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B2C966E8E5EF5C40FD2D5B7 /* Pods_JokesApp_JokesAppUITests.framework */; }; 11 | 611FC29A57610424D85037B1 /* Pods_JokesApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64893F03D4A215C2FF1C9644 /* Pods_JokesApp.framework */; }; 12 | 750CAE582698BAAF00C9B191 /* JokesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750CAE572698BAAF00C9B191 /* JokesView.swift */; }; 13 | 750CAE682698BCEC00C9B191 /* JokesViewModelWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750CAE672698BCEC00C9B191 /* JokesViewModelWrapper.swift */; }; 14 | 750CAE6E2698BF7200C9B191 /* Ktor_ioCloseable+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750CAE6D2698BF7200C9B191 /* Ktor_ioCloseable+.swift */; }; 15 | 750CAE7A2698BFB700C9B191 /* ViewModelWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750CAE792698BFB700C9B191 /* ViewModelWrapper.swift */; }; 16 | 750CAEE62698C7C900C9B191 /* JokesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750CAEE52698C7C900C9B191 /* JokesApp.swift */; }; 17 | 85ED90DD61381871878B5FD8 /* Pods_JokesAppTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42E9E5D234D7A8F30473FE34 /* Pods_JokesAppTests.framework */; }; 18 | E5CAC8432473E2A50043D8A6 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = E52A09C72323E22D000AA086 /* libsqlite3.tbd */; }; 19 | E8081AE0230C32BE00F58819 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E8081ADF230C32BE00F58819 /* Assets.xcassets */; }; 20 | E8081AEE230C32BE00F58819 /* mppexampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8081AED230C32BE00F58819 /* mppexampleTests.swift */; }; 21 | E8081AF9230C32BE00F58819 /* mppexampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8081AF8230C32BE00F58819 /* mppexampleUITests.swift */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | E8081AEA230C32BE00F58819 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = E8081ACD230C32BD00F58819 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = E8081AD4230C32BD00F58819; 30 | remoteInfo = mppexample; 31 | }; 32 | E8081AF5230C32BE00F58819 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = E8081ACD230C32BD00F58819 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = E8081AD4230C32BD00F58819; 37 | remoteInfo = mppexample; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 111E58C7CB97D2CBF3105E9C /* Pods-JokesAppTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JokesAppTests.debug.xcconfig"; path = "Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests.debug.xcconfig"; sourceTree = ""; }; 43 | 2B2C966E8E5EF5C40FD2D5B7 /* Pods_JokesApp_JokesAppUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_JokesApp_JokesAppUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 39810C8DCF329D4D0FBA73C3 /* Pods-JokesApp-JokesAppUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JokesApp-JokesAppUITests.debug.xcconfig"; path = "Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests.debug.xcconfig"; sourceTree = ""; }; 45 | 42E9E5D234D7A8F30473FE34 /* Pods_JokesAppTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_JokesAppTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 43ECA600FAB0A90F3DDC4BEE /* Pods-JokesApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JokesApp.release.xcconfig"; path = "Target Support Files/Pods-JokesApp/Pods-JokesApp.release.xcconfig"; sourceTree = ""; }; 47 | 6441EF089F9770161A1638C1 /* Pods-JokesApp-JokesAppUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JokesApp-JokesAppUITests.release.xcconfig"; path = "Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests.release.xcconfig"; sourceTree = ""; }; 48 | 64893F03D4A215C2FF1C9644 /* Pods_JokesApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_JokesApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 6BC2D464EC6F37B4BD4901B2 /* Pods-JokesApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JokesApp.debug.xcconfig"; path = "Target Support Files/Pods-JokesApp/Pods-JokesApp.debug.xcconfig"; sourceTree = ""; }; 50 | 750CAE572698BAAF00C9B191 /* JokesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JokesView.swift; sourceTree = ""; }; 51 | 750CAE672698BCEC00C9B191 /* JokesViewModelWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JokesViewModelWrapper.swift; sourceTree = ""; }; 52 | 750CAE6D2698BF7200C9B191 /* Ktor_ioCloseable+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Ktor_ioCloseable+.swift"; sourceTree = ""; }; 53 | 750CAE792698BFB700C9B191 /* ViewModelWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModelWrapper.swift; sourceTree = ""; }; 54 | 750CAEE52698C7C900C9B191 /* JokesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JokesApp.swift; sourceTree = ""; }; 55 | D2F9FFEADC09A5F693217D72 /* Pods-JokesAppTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JokesAppTests.release.xcconfig"; path = "Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests.release.xcconfig"; sourceTree = ""; }; 56 | E52A09C72323E22D000AA086 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; 57 | E8081AD5230C32BD00F58819 /* JokesApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JokesApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | E8081ADF230C32BE00F58819 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 59 | E8081AE4230C32BE00F58819 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | E8081AE9230C32BE00F58819 /* JokesAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JokesAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | E8081AED230C32BE00F58819 /* mppexampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = mppexampleTests.swift; sourceTree = ""; }; 62 | E8081AEF230C32BE00F58819 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | E8081AF4230C32BE00F58819 /* JokesAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JokesAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | E8081AF8230C32BE00F58819 /* mppexampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = mppexampleUITests.swift; sourceTree = ""; }; 65 | E8081AFA230C32BE00F58819 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | E8081AD2230C32BD00F58819 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | E5CAC8432473E2A50043D8A6 /* libsqlite3.tbd in Frameworks */, 74 | 611FC29A57610424D85037B1 /* Pods_JokesApp.framework in Frameworks */, 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | E8081AE6230C32BE00F58819 /* Frameworks */ = { 79 | isa = PBXFrameworksBuildPhase; 80 | buildActionMask = 2147483647; 81 | files = ( 82 | 85ED90DD61381871878B5FD8 /* Pods_JokesAppTests.framework in Frameworks */, 83 | ); 84 | runOnlyForDeploymentPostprocessing = 0; 85 | }; 86 | E8081AF1230C32BE00F58819 /* Frameworks */ = { 87 | isa = PBXFrameworksBuildPhase; 88 | buildActionMask = 2147483647; 89 | files = ( 90 | 0BF61F917C389A38B94C302B /* Pods_JokesApp_JokesAppUITests.framework in Frameworks */, 91 | ); 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | /* End PBXFrameworksBuildPhase section */ 95 | 96 | /* Begin PBXGroup section */ 97 | 750CAE6C2698BF6600C9B191 /* extensions */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 750CAE6D2698BF7200C9B191 /* Ktor_ioCloseable+.swift */, 101 | ); 102 | path = extensions; 103 | sourceTree = ""; 104 | }; 105 | 750CAE782698BFAD00C9B191 /* utils */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 750CAE792698BFB700C9B191 /* ViewModelWrapper.swift */, 109 | ); 110 | path = utils; 111 | sourceTree = ""; 112 | }; 113 | 81E8F34CB1229463C3D615B1 /* Pods */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 6BC2D464EC6F37B4BD4901B2 /* Pods-JokesApp.debug.xcconfig */, 117 | 43ECA600FAB0A90F3DDC4BEE /* Pods-JokesApp.release.xcconfig */, 118 | 39810C8DCF329D4D0FBA73C3 /* Pods-JokesApp-JokesAppUITests.debug.xcconfig */, 119 | 6441EF089F9770161A1638C1 /* Pods-JokesApp-JokesAppUITests.release.xcconfig */, 120 | 111E58C7CB97D2CBF3105E9C /* Pods-JokesAppTests.debug.xcconfig */, 121 | D2F9FFEADC09A5F693217D72 /* Pods-JokesAppTests.release.xcconfig */, 122 | ); 123 | path = Pods; 124 | sourceTree = ""; 125 | }; 126 | E52A09C62323E22C000AA086 /* Frameworks */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | E52A09C72323E22D000AA086 /* libsqlite3.tbd */, 130 | 64893F03D4A215C2FF1C9644 /* Pods_JokesApp.framework */, 131 | 2B2C966E8E5EF5C40FD2D5B7 /* Pods_JokesApp_JokesAppUITests.framework */, 132 | 42E9E5D234D7A8F30473FE34 /* Pods_JokesAppTests.framework */, 133 | ); 134 | name = Frameworks; 135 | sourceTree = ""; 136 | }; 137 | E8081ACC230C32BD00F58819 = { 138 | isa = PBXGroup; 139 | children = ( 140 | E8081AD7230C32BD00F58819 /* JokesApp */, 141 | E8081AEC230C32BE00F58819 /* JokesAppTests */, 142 | E8081AF7230C32BE00F58819 /* JokesAppUITests */, 143 | E8081AD6230C32BD00F58819 /* Products */, 144 | E52A09C62323E22C000AA086 /* Frameworks */, 145 | 81E8F34CB1229463C3D615B1 /* Pods */, 146 | ); 147 | sourceTree = ""; 148 | }; 149 | E8081AD6230C32BD00F58819 /* Products */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | E8081AD5230C32BD00F58819 /* JokesApp.app */, 153 | E8081AE9230C32BE00F58819 /* JokesAppTests.xctest */, 154 | E8081AF4230C32BE00F58819 /* JokesAppUITests.xctest */, 155 | ); 156 | name = Products; 157 | sourceTree = ""; 158 | }; 159 | E8081AD7230C32BD00F58819 /* JokesApp */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 750CAE782698BFAD00C9B191 /* utils */, 163 | 750CAE6C2698BF6600C9B191 /* extensions */, 164 | E8081ADF230C32BE00F58819 /* Assets.xcassets */, 165 | E8081AE4230C32BE00F58819 /* Info.plist */, 166 | 750CAE572698BAAF00C9B191 /* JokesView.swift */, 167 | 750CAE672698BCEC00C9B191 /* JokesViewModelWrapper.swift */, 168 | 750CAEE52698C7C900C9B191 /* JokesApp.swift */, 169 | ); 170 | path = JokesApp; 171 | sourceTree = ""; 172 | }; 173 | E8081AEC230C32BE00F58819 /* JokesAppTests */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | E8081AED230C32BE00F58819 /* mppexampleTests.swift */, 177 | E8081AEF230C32BE00F58819 /* Info.plist */, 178 | ); 179 | path = JokesAppTests; 180 | sourceTree = ""; 181 | }; 182 | E8081AF7230C32BE00F58819 /* JokesAppUITests */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | E8081AF8230C32BE00F58819 /* mppexampleUITests.swift */, 186 | E8081AFA230C32BE00F58819 /* Info.plist */, 187 | ); 188 | path = JokesAppUITests; 189 | sourceTree = ""; 190 | }; 191 | /* End PBXGroup section */ 192 | 193 | /* Begin PBXNativeTarget section */ 194 | E8081AD4230C32BD00F58819 /* JokesApp */ = { 195 | isa = PBXNativeTarget; 196 | buildConfigurationList = E8081AFD230C32BE00F58819 /* Build configuration list for PBXNativeTarget "JokesApp" */; 197 | buildPhases = ( 198 | 979EFC1F48B2551116977E83 /* [CP] Check Pods Manifest.lock */, 199 | E8081AD1230C32BD00F58819 /* Sources */, 200 | E8081AD2230C32BD00F58819 /* Frameworks */, 201 | E8081AD3230C32BD00F58819 /* Resources */, 202 | ); 203 | buildRules = ( 204 | ); 205 | dependencies = ( 206 | ); 207 | name = JokesApp; 208 | productName = mppexample; 209 | productReference = E8081AD5230C32BD00F58819 /* JokesApp.app */; 210 | productType = "com.apple.product-type.application"; 211 | }; 212 | E8081AE8230C32BE00F58819 /* JokesAppTests */ = { 213 | isa = PBXNativeTarget; 214 | buildConfigurationList = E8081B00230C32BE00F58819 /* Build configuration list for PBXNativeTarget "JokesAppTests" */; 215 | buildPhases = ( 216 | 415A2A3F0039F14E276ECC26 /* [CP] Check Pods Manifest.lock */, 217 | E8081AE5230C32BE00F58819 /* Sources */, 218 | E8081AE6230C32BE00F58819 /* Frameworks */, 219 | E8081AE7230C32BE00F58819 /* Resources */, 220 | ); 221 | buildRules = ( 222 | ); 223 | dependencies = ( 224 | E8081AEB230C32BE00F58819 /* PBXTargetDependency */, 225 | ); 226 | name = JokesAppTests; 227 | productName = mppexampleTests; 228 | productReference = E8081AE9230C32BE00F58819 /* JokesAppTests.xctest */; 229 | productType = "com.apple.product-type.bundle.unit-test"; 230 | }; 231 | E8081AF3230C32BE00F58819 /* JokesAppUITests */ = { 232 | isa = PBXNativeTarget; 233 | buildConfigurationList = E8081B03230C32BE00F58819 /* Build configuration list for PBXNativeTarget "JokesAppUITests" */; 234 | buildPhases = ( 235 | 1723E1EEFF7D13053BA1F14E /* [CP] Check Pods Manifest.lock */, 236 | E8081AF0230C32BE00F58819 /* Sources */, 237 | E8081AF1230C32BE00F58819 /* Frameworks */, 238 | E8081AF2230C32BE00F58819 /* Resources */, 239 | ); 240 | buildRules = ( 241 | ); 242 | dependencies = ( 243 | E8081AF6230C32BE00F58819 /* PBXTargetDependency */, 244 | ); 245 | name = JokesAppUITests; 246 | productName = mppexampleUITests; 247 | productReference = E8081AF4230C32BE00F58819 /* JokesAppUITests.xctest */; 248 | productType = "com.apple.product-type.bundle.ui-testing"; 249 | }; 250 | /* End PBXNativeTarget section */ 251 | 252 | /* Begin PBXProject section */ 253 | E8081ACD230C32BD00F58819 /* Project object */ = { 254 | isa = PBXProject; 255 | attributes = { 256 | LastSwiftUpdateCheck = 1030; 257 | LastUpgradeCheck = 1030; 258 | ORGANIZATIONNAME = Kurt; 259 | TargetAttributes = { 260 | E8081AD4230C32BD00F58819 = { 261 | CreatedOnToolsVersion = 10.3; 262 | }; 263 | E8081AE8230C32BE00F58819 = { 264 | CreatedOnToolsVersion = 10.3; 265 | TestTargetID = E8081AD4230C32BD00F58819; 266 | }; 267 | E8081AF3230C32BE00F58819 = { 268 | CreatedOnToolsVersion = 10.3; 269 | TestTargetID = E8081AD4230C32BD00F58819; 270 | }; 271 | }; 272 | }; 273 | buildConfigurationList = E8081AD0230C32BD00F58819 /* Build configuration list for PBXProject "JokesApp" */; 274 | compatibilityVersion = "Xcode 9.3"; 275 | developmentRegion = en; 276 | hasScannedForEncodings = 0; 277 | knownRegions = ( 278 | en, 279 | Base, 280 | ); 281 | mainGroup = E8081ACC230C32BD00F58819; 282 | productRefGroup = E8081AD6230C32BD00F58819 /* Products */; 283 | projectDirPath = ""; 284 | projectRoot = ""; 285 | targets = ( 286 | E8081AD4230C32BD00F58819 /* JokesApp */, 287 | E8081AE8230C32BE00F58819 /* JokesAppTests */, 288 | E8081AF3230C32BE00F58819 /* JokesAppUITests */, 289 | ); 290 | }; 291 | /* End PBXProject section */ 292 | 293 | /* Begin PBXResourcesBuildPhase section */ 294 | E8081AD3230C32BD00F58819 /* Resources */ = { 295 | isa = PBXResourcesBuildPhase; 296 | buildActionMask = 2147483647; 297 | files = ( 298 | E8081AE0230C32BE00F58819 /* Assets.xcassets in Resources */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | E8081AE7230C32BE00F58819 /* Resources */ = { 303 | isa = PBXResourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | E8081AF2230C32BE00F58819 /* Resources */ = { 310 | isa = PBXResourcesBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | /* End PBXResourcesBuildPhase section */ 317 | 318 | /* Begin PBXShellScriptBuildPhase section */ 319 | 1723E1EEFF7D13053BA1F14E /* [CP] Check Pods Manifest.lock */ = { 320 | isa = PBXShellScriptBuildPhase; 321 | buildActionMask = 2147483647; 322 | files = ( 323 | ); 324 | inputFileListPaths = ( 325 | ); 326 | inputPaths = ( 327 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 328 | "${PODS_ROOT}/Manifest.lock", 329 | ); 330 | name = "[CP] Check Pods Manifest.lock"; 331 | outputFileListPaths = ( 332 | ); 333 | outputPaths = ( 334 | "$(DERIVED_FILE_DIR)/Pods-JokesApp-JokesAppUITests-checkManifestLockResult.txt", 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | shellPath = /bin/sh; 338 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 339 | showEnvVarsInLog = 0; 340 | }; 341 | 415A2A3F0039F14E276ECC26 /* [CP] Check Pods Manifest.lock */ = { 342 | isa = PBXShellScriptBuildPhase; 343 | buildActionMask = 2147483647; 344 | files = ( 345 | ); 346 | inputFileListPaths = ( 347 | ); 348 | inputPaths = ( 349 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 350 | "${PODS_ROOT}/Manifest.lock", 351 | ); 352 | name = "[CP] Check Pods Manifest.lock"; 353 | outputFileListPaths = ( 354 | ); 355 | outputPaths = ( 356 | "$(DERIVED_FILE_DIR)/Pods-JokesAppTests-checkManifestLockResult.txt", 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | shellPath = /bin/sh; 360 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 361 | showEnvVarsInLog = 0; 362 | }; 363 | 979EFC1F48B2551116977E83 /* [CP] Check Pods Manifest.lock */ = { 364 | isa = PBXShellScriptBuildPhase; 365 | buildActionMask = 2147483647; 366 | files = ( 367 | ); 368 | inputFileListPaths = ( 369 | ); 370 | inputPaths = ( 371 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 372 | "${PODS_ROOT}/Manifest.lock", 373 | ); 374 | name = "[CP] Check Pods Manifest.lock"; 375 | outputFileListPaths = ( 376 | ); 377 | outputPaths = ( 378 | "$(DERIVED_FILE_DIR)/Pods-JokesApp-checkManifestLockResult.txt", 379 | ); 380 | runOnlyForDeploymentPostprocessing = 0; 381 | shellPath = /bin/sh; 382 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 383 | showEnvVarsInLog = 0; 384 | }; 385 | /* End PBXShellScriptBuildPhase section */ 386 | 387 | /* Begin PBXSourcesBuildPhase section */ 388 | E8081AD1230C32BD00F58819 /* Sources */ = { 389 | isa = PBXSourcesBuildPhase; 390 | buildActionMask = 2147483647; 391 | files = ( 392 | 750CAE582698BAAF00C9B191 /* JokesView.swift in Sources */, 393 | 750CAE6E2698BF7200C9B191 /* Ktor_ioCloseable+.swift in Sources */, 394 | 750CAE7A2698BFB700C9B191 /* ViewModelWrapper.swift in Sources */, 395 | 750CAE682698BCEC00C9B191 /* JokesViewModelWrapper.swift in Sources */, 396 | 750CAEE62698C7C900C9B191 /* JokesApp.swift in Sources */, 397 | ); 398 | runOnlyForDeploymentPostprocessing = 0; 399 | }; 400 | E8081AE5230C32BE00F58819 /* Sources */ = { 401 | isa = PBXSourcesBuildPhase; 402 | buildActionMask = 2147483647; 403 | files = ( 404 | E8081AEE230C32BE00F58819 /* mppexampleTests.swift in Sources */, 405 | ); 406 | runOnlyForDeploymentPostprocessing = 0; 407 | }; 408 | E8081AF0230C32BE00F58819 /* Sources */ = { 409 | isa = PBXSourcesBuildPhase; 410 | buildActionMask = 2147483647; 411 | files = ( 412 | E8081AF9230C32BE00F58819 /* mppexampleUITests.swift in Sources */, 413 | ); 414 | runOnlyForDeploymentPostprocessing = 0; 415 | }; 416 | /* End PBXSourcesBuildPhase section */ 417 | 418 | /* Begin PBXTargetDependency section */ 419 | E8081AEB230C32BE00F58819 /* PBXTargetDependency */ = { 420 | isa = PBXTargetDependency; 421 | target = E8081AD4230C32BD00F58819 /* JokesApp */; 422 | targetProxy = E8081AEA230C32BE00F58819 /* PBXContainerItemProxy */; 423 | }; 424 | E8081AF6230C32BE00F58819 /* PBXTargetDependency */ = { 425 | isa = PBXTargetDependency; 426 | target = E8081AD4230C32BD00F58819 /* JokesApp */; 427 | targetProxy = E8081AF5230C32BE00F58819 /* PBXContainerItemProxy */; 428 | }; 429 | /* End PBXTargetDependency section */ 430 | 431 | /* Begin XCBuildConfiguration section */ 432 | E8081AFB230C32BE00F58819 /* Debug */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ALWAYS_SEARCH_USER_PATHS = NO; 436 | CLANG_ANALYZER_NONNULL = YES; 437 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 438 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 439 | CLANG_CXX_LIBRARY = "libc++"; 440 | CLANG_ENABLE_MODULES = YES; 441 | CLANG_ENABLE_OBJC_ARC = YES; 442 | CLANG_ENABLE_OBJC_WEAK = YES; 443 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 444 | CLANG_WARN_BOOL_CONVERSION = YES; 445 | CLANG_WARN_COMMA = YES; 446 | CLANG_WARN_CONSTANT_CONVERSION = YES; 447 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 448 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 449 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 450 | CLANG_WARN_EMPTY_BODY = YES; 451 | CLANG_WARN_ENUM_CONVERSION = YES; 452 | CLANG_WARN_INFINITE_RECURSION = YES; 453 | CLANG_WARN_INT_CONVERSION = YES; 454 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 455 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 456 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 457 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 458 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 459 | CLANG_WARN_STRICT_PROTOTYPES = YES; 460 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 461 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 462 | CLANG_WARN_UNREACHABLE_CODE = YES; 463 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 464 | CODE_SIGN_IDENTITY = "iPhone Developer"; 465 | COPY_PHASE_STRIP = NO; 466 | DEBUG_INFORMATION_FORMAT = dwarf; 467 | ENABLE_STRICT_OBJC_MSGSEND = YES; 468 | ENABLE_TESTABILITY = YES; 469 | GCC_C_LANGUAGE_STANDARD = gnu11; 470 | GCC_DYNAMIC_NO_PIC = NO; 471 | GCC_NO_COMMON_BLOCKS = YES; 472 | GCC_OPTIMIZATION_LEVEL = 0; 473 | GCC_PREPROCESSOR_DEFINITIONS = ( 474 | "DEBUG=1", 475 | "$(inherited)", 476 | ); 477 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 478 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 479 | GCC_WARN_UNDECLARED_SELECTOR = YES; 480 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 481 | GCC_WARN_UNUSED_FUNCTION = YES; 482 | GCC_WARN_UNUSED_VARIABLE = YES; 483 | IPHONEOS_DEPLOYMENT_TARGET = 14.4; 484 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 485 | MTL_FAST_MATH = YES; 486 | ONLY_ACTIVE_ARCH = YES; 487 | OTHER_LDFLAGS = "${inherited}"; 488 | SDKROOT = iphoneos; 489 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 490 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 491 | }; 492 | name = Debug; 493 | }; 494 | E8081AFC230C32BE00F58819 /* Release */ = { 495 | isa = XCBuildConfiguration; 496 | buildSettings = { 497 | ALWAYS_SEARCH_USER_PATHS = NO; 498 | CLANG_ANALYZER_NONNULL = YES; 499 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 500 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 501 | CLANG_CXX_LIBRARY = "libc++"; 502 | CLANG_ENABLE_MODULES = YES; 503 | CLANG_ENABLE_OBJC_ARC = YES; 504 | CLANG_ENABLE_OBJC_WEAK = YES; 505 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 506 | CLANG_WARN_BOOL_CONVERSION = YES; 507 | CLANG_WARN_COMMA = YES; 508 | CLANG_WARN_CONSTANT_CONVERSION = YES; 509 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 510 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 511 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 512 | CLANG_WARN_EMPTY_BODY = YES; 513 | CLANG_WARN_ENUM_CONVERSION = YES; 514 | CLANG_WARN_INFINITE_RECURSION = YES; 515 | CLANG_WARN_INT_CONVERSION = YES; 516 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 517 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 518 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 519 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 520 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 521 | CLANG_WARN_STRICT_PROTOTYPES = YES; 522 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 523 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 524 | CLANG_WARN_UNREACHABLE_CODE = YES; 525 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 526 | CODE_SIGN_IDENTITY = "iPhone Developer"; 527 | COPY_PHASE_STRIP = NO; 528 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 529 | ENABLE_NS_ASSERTIONS = NO; 530 | ENABLE_STRICT_OBJC_MSGSEND = YES; 531 | GCC_C_LANGUAGE_STANDARD = gnu11; 532 | GCC_NO_COMMON_BLOCKS = YES; 533 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 534 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 535 | GCC_WARN_UNDECLARED_SELECTOR = YES; 536 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 537 | GCC_WARN_UNUSED_FUNCTION = YES; 538 | GCC_WARN_UNUSED_VARIABLE = YES; 539 | IPHONEOS_DEPLOYMENT_TARGET = 14.4; 540 | MTL_ENABLE_DEBUG_INFO = NO; 541 | MTL_FAST_MATH = YES; 542 | OTHER_LDFLAGS = "${inherited}"; 543 | SDKROOT = iphoneos; 544 | SWIFT_COMPILATION_MODE = wholemodule; 545 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 546 | VALIDATE_PRODUCT = YES; 547 | }; 548 | name = Release; 549 | }; 550 | E8081AFE230C32BE00F58819 /* Debug */ = { 551 | isa = XCBuildConfiguration; 552 | baseConfigurationReference = 6BC2D464EC6F37B4BD4901B2 /* Pods-JokesApp.debug.xcconfig */; 553 | buildSettings = { 554 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 555 | CODE_SIGN_STYLE = Automatic; 556 | FRAMEWORK_SEARCH_PATHS = ( 557 | "${PROJECT_DIR}/../common/build/xcode-frameworks", 558 | "${PROJECT_DIR}", 559 | "${inherited}", 560 | ); 561 | INFOPLIST_FILE = "$(SRCROOT)/JokesApp/Info.plist"; 562 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 563 | LD_RUNPATH_SEARCH_PATHS = ( 564 | "$(inherited)", 565 | "@executable_path/Frameworks", 566 | ); 567 | OTHER_LDFLAGS = "${inherited}"; 568 | PRODUCT_BUNDLE_IDENTIFIER = com.kurt.jokes; 569 | PRODUCT_NAME = "$(TARGET_NAME)"; 570 | SWIFT_VERSION = 5.0; 571 | TARGETED_DEVICE_FAMILY = "1,2"; 572 | }; 573 | name = Debug; 574 | }; 575 | E8081AFF230C32BE00F58819 /* Release */ = { 576 | isa = XCBuildConfiguration; 577 | baseConfigurationReference = 43ECA600FAB0A90F3DDC4BEE /* Pods-JokesApp.release.xcconfig */; 578 | buildSettings = { 579 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 580 | CODE_SIGN_STYLE = Automatic; 581 | FRAMEWORK_SEARCH_PATHS = ( 582 | "${PROJECT_DIR}/../common/build/xcode-frameworks", 583 | "${PROJECT_DIR}", 584 | "${inherited}", 585 | ); 586 | INFOPLIST_FILE = "$(SRCROOT)/JokesApp/Info.plist"; 587 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 588 | LD_RUNPATH_SEARCH_PATHS = ( 589 | "$(inherited)", 590 | "@executable_path/Frameworks", 591 | ); 592 | OTHER_LDFLAGS = "${inherited}"; 593 | PRODUCT_BUNDLE_IDENTIFIER = com.kurt.jokes; 594 | PRODUCT_NAME = "$(TARGET_NAME)"; 595 | SWIFT_VERSION = 5.0; 596 | TARGETED_DEVICE_FAMILY = "1,2"; 597 | }; 598 | name = Release; 599 | }; 600 | E8081B01230C32BE00F58819 /* Debug */ = { 601 | isa = XCBuildConfiguration; 602 | baseConfigurationReference = 111E58C7CB97D2CBF3105E9C /* Pods-JokesAppTests.debug.xcconfig */; 603 | buildSettings = { 604 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 605 | BUNDLE_LOADER = "$(TEST_HOST)"; 606 | CODE_SIGN_STYLE = Automatic; 607 | INFOPLIST_FILE = mppexampleTests/Info.plist; 608 | LD_RUNPATH_SEARCH_PATHS = ( 609 | "$(inherited)", 610 | "@executable_path/Frameworks", 611 | "@loader_path/Frameworks", 612 | ); 613 | PRODUCT_BUNDLE_IDENTIFIER = com.kurt.mppexampleTests; 614 | PRODUCT_NAME = "$(TARGET_NAME)"; 615 | SWIFT_VERSION = 5.0; 616 | TARGETED_DEVICE_FAMILY = "1,2"; 617 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/JokesApp.app/JokesApp"; 618 | }; 619 | name = Debug; 620 | }; 621 | E8081B02230C32BE00F58819 /* Release */ = { 622 | isa = XCBuildConfiguration; 623 | baseConfigurationReference = D2F9FFEADC09A5F693217D72 /* Pods-JokesAppTests.release.xcconfig */; 624 | buildSettings = { 625 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 626 | BUNDLE_LOADER = "$(TEST_HOST)"; 627 | CODE_SIGN_STYLE = Automatic; 628 | INFOPLIST_FILE = mppexampleTests/Info.plist; 629 | LD_RUNPATH_SEARCH_PATHS = ( 630 | "$(inherited)", 631 | "@executable_path/Frameworks", 632 | "@loader_path/Frameworks", 633 | ); 634 | PRODUCT_BUNDLE_IDENTIFIER = com.kurt.mppexampleTests; 635 | PRODUCT_NAME = "$(TARGET_NAME)"; 636 | SWIFT_VERSION = 5.0; 637 | TARGETED_DEVICE_FAMILY = "1,2"; 638 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/JokesApp.app/JokesApp"; 639 | }; 640 | name = Release; 641 | }; 642 | E8081B04230C32BE00F58819 /* Debug */ = { 643 | isa = XCBuildConfiguration; 644 | baseConfigurationReference = 39810C8DCF329D4D0FBA73C3 /* Pods-JokesApp-JokesAppUITests.debug.xcconfig */; 645 | buildSettings = { 646 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 647 | CODE_SIGN_STYLE = Automatic; 648 | INFOPLIST_FILE = mppexampleUITests/Info.plist; 649 | LD_RUNPATH_SEARCH_PATHS = ( 650 | "$(inherited)", 651 | "@executable_path/Frameworks", 652 | "@loader_path/Frameworks", 653 | ); 654 | PRODUCT_BUNDLE_IDENTIFIER = com.kurt.mppexampleUITests; 655 | PRODUCT_NAME = "$(TARGET_NAME)"; 656 | SWIFT_VERSION = 5.0; 657 | TARGETED_DEVICE_FAMILY = "1,2"; 658 | TEST_TARGET_NAME = mppexample; 659 | }; 660 | name = Debug; 661 | }; 662 | E8081B05230C32BE00F58819 /* Release */ = { 663 | isa = XCBuildConfiguration; 664 | baseConfigurationReference = 6441EF089F9770161A1638C1 /* Pods-JokesApp-JokesAppUITests.release.xcconfig */; 665 | buildSettings = { 666 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 667 | CODE_SIGN_STYLE = Automatic; 668 | INFOPLIST_FILE = mppexampleUITests/Info.plist; 669 | LD_RUNPATH_SEARCH_PATHS = ( 670 | "$(inherited)", 671 | "@executable_path/Frameworks", 672 | "@loader_path/Frameworks", 673 | ); 674 | PRODUCT_BUNDLE_IDENTIFIER = com.kurt.mppexampleUITests; 675 | PRODUCT_NAME = "$(TARGET_NAME)"; 676 | SWIFT_VERSION = 5.0; 677 | TARGETED_DEVICE_FAMILY = "1,2"; 678 | TEST_TARGET_NAME = mppexample; 679 | }; 680 | name = Release; 681 | }; 682 | /* End XCBuildConfiguration section */ 683 | 684 | /* Begin XCConfigurationList section */ 685 | E8081AD0230C32BD00F58819 /* Build configuration list for PBXProject "JokesApp" */ = { 686 | isa = XCConfigurationList; 687 | buildConfigurations = ( 688 | E8081AFB230C32BE00F58819 /* Debug */, 689 | E8081AFC230C32BE00F58819 /* Release */, 690 | ); 691 | defaultConfigurationIsVisible = 0; 692 | defaultConfigurationName = Release; 693 | }; 694 | E8081AFD230C32BE00F58819 /* Build configuration list for PBXNativeTarget "JokesApp" */ = { 695 | isa = XCConfigurationList; 696 | buildConfigurations = ( 697 | E8081AFE230C32BE00F58819 /* Debug */, 698 | E8081AFF230C32BE00F58819 /* Release */, 699 | ); 700 | defaultConfigurationIsVisible = 0; 701 | defaultConfigurationName = Release; 702 | }; 703 | E8081B00230C32BE00F58819 /* Build configuration list for PBXNativeTarget "JokesAppTests" */ = { 704 | isa = XCConfigurationList; 705 | buildConfigurations = ( 706 | E8081B01230C32BE00F58819 /* Debug */, 707 | E8081B02230C32BE00F58819 /* Release */, 708 | ); 709 | defaultConfigurationIsVisible = 0; 710 | defaultConfigurationName = Release; 711 | }; 712 | E8081B03230C32BE00F58819 /* Build configuration list for PBXNativeTarget "JokesAppUITests" */ = { 713 | isa = XCConfigurationList; 714 | buildConfigurations = ( 715 | E8081B04230C32BE00F58819 /* Debug */, 716 | E8081B05230C32BE00F58819 /* Release */, 717 | ); 718 | defaultConfigurationIsVisible = 0; 719 | defaultConfigurationName = Release; 720 | }; 721 | /* End XCConfigurationList section */ 722 | }; 723 | rootObject = E8081ACD230C32BD00F58819 /* Project object */; 724 | } 725 | -------------------------------------------------------------------------------- /iosApp/JokesApp.xcodeproj/xcshareddata/xcschemes/mppexample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /iosApp/JokesApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /iosApp/JokesApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iosApp/JokesApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /iosApp/JokesApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iosApp/JokesApp/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Test 4 | // 5 | // Created by Kurt Renzo Acosta on 7/10/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | var body: some View { 12 | Text("Hello, worldasdf!") 13 | .padding() 14 | } 15 | } 16 | 17 | struct ContentView_Previews: PreviewProvider { 18 | static var previews: some View { 19 | ContentView() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iosApp/JokesApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UIApplicationSupportsIndirectInputEvents 29 | 30 | UILaunchScreen 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 | 50 | 51 | -------------------------------------------------------------------------------- /iosApp/JokesApp/JokesApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JokesApp.swift 3 | // JokesApp 4 | // 5 | // Created by Kurt Renzo Acosta on 7/10/21. 6 | // Copyright © 2021 Kurt. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | @main 12 | struct JokesApp : App { 13 | var body: some Scene { 14 | WindowGroup { 15 | JokesView() 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /iosApp/JokesApp/JokesView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JokesView.swift 3 | // JokesApp 4 | // 5 | // Created by Kurt Renzo Acosta on 7/10/21. 6 | // Copyright © 2021 Kurt. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import JokesShared 11 | 12 | struct JokesView: View { 13 | @StateObject var viewModel = JokesViewModelWrapper() 14 | 15 | var body: some View { 16 | ZStack { 17 | if (viewModel.jokesState is UiState.Loading) { 18 | ProgressView() 19 | } else { 20 | List { 21 | ForEach(viewModel.jokes, id: \.id) { joke in 22 | JokeItem(joke: joke) 23 | } 24 | } 25 | } 26 | }.onAppear { 27 | viewModel.onStart() 28 | } 29 | } 30 | } 31 | 32 | struct JokeItem: View { 33 | var joke: Joke 34 | 35 | @State private var isPunchlineVisible = false 36 | 37 | var body: some View { 38 | VStack(alignment: .leading) { 39 | Text(joke.setup).fontWeight(.bold) 40 | if (isPunchlineVisible) { 41 | Text(joke.punchline) 42 | } 43 | }.padding(8) 44 | .onTapGesture { 45 | isPunchlineVisible = !isPunchlineVisible 46 | } 47 | } 48 | 49 | } 50 | 51 | struct JokesView_Previews: PreviewProvider { 52 | static var previews: some View { 53 | JokesView() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /iosApp/JokesApp/JokesViewModelWrapper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JokesViewModelWrapper.swift 3 | // JokesApp 4 | // 5 | // Created by Kurt Renzo Acosta on 7/10/21. 6 | // Copyright © 2021 Kurt. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import JokesShared 11 | 12 | class JokesViewModelWrapper : ViewModelWrapper, ObservableObject { 13 | @Published var jokes: [Joke] = [] 14 | @Published var jokesState: UiState = UiState.Loading() 15 | 16 | let viewModel = JokesViewModel.Companion.init().create() 17 | 18 | func onStart() { 19 | viewModel.jokes.watch { (jokesNullable) in 20 | guard let ktJokes = jokesNullable as? [Joke] else { 21 | return 22 | } 23 | self.jokes = ktJokes 24 | }.addToCloseables(self) 25 | 26 | viewModel.jokesState.watch { (uiStateNullable) in 27 | guard let uiState = uiStateNullable else { 28 | return 29 | } 30 | self.jokesState = uiState 31 | }.addToCloseables(self) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /iosApp/JokesApp/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // mppexample 4 | // 5 | // Created by Kurt on 20/08/2019. 6 | // Copyright © 2019 Kurt. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import JokesShared 11 | 12 | class ViewController: UITableViewController { 13 | // MARK: Properties 14 | var jokes = [Joke]() 15 | var visibleJokes = Set() 16 | 17 | let viewModel = JokesViewModel.Companion.init().create() 18 | var closeables = [Ktor_ioCloseable]() 19 | 20 | deinit { 21 | closeables.forEach { (closeable) in 22 | closeable.close() 23 | } 24 | } 25 | 26 | override func viewDidLoad() { 27 | super.viewDidLoad() 28 | 29 | closeables.append( 30 | viewModel.jokes.watch { jokesNullable in 31 | if let jokes = jokesNullable { 32 | self.jokes += jokes as! Array 33 | self.tableView.reloadData() 34 | } 35 | } 36 | ) 37 | 38 | 39 | closeables.append( 40 | viewModel.jokesState.watch { jokesStateNullable in 41 | if let jokesState = jokesStateNullable { 42 | jokesState 43 | } 44 | } 45 | ) 46 | } 47 | 48 | override func numberOfSections(in tableView: UITableView) -> Int { 49 | return 1 50 | } 51 | 52 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 53 | return jokes.count 54 | } 55 | 56 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 57 | guard let cell = tableView.dequeueReusableCell(withIdentifier: "JokesTableViewCell", for: indexPath) as? JokesTableViewCell else { 58 | fatalError("The dequeued cell is not an instance of JokesTableViewCell.") 59 | } 60 | 61 | let joke = jokes[indexPath.row] 62 | 63 | cell.txtSetup.text = joke.setup 64 | cell.txtPunchline.text = joke.punchline 65 | cell.txtPunchline.isHidden = !visibleJokes.contains(indexPath.row) 66 | 67 | return cell 68 | } 69 | 70 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 71 | guard let cell = tableView.cellForRow(at: indexPath) as? JokesTableViewCell else { 72 | fatalError("The cell is not an instance of JokesTableViewCell.") 73 | } 74 | if (visibleJokes.contains(indexPath.row)) { 75 | visibleJokes.remove(indexPath.row) 76 | } else { 77 | visibleJokes.insert(indexPath.row) 78 | } 79 | cell.txtPunchline.isHidden = !cell.txtPunchline.isHidden 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /iosApp/JokesApp/extensions/Ktor_ioCloseable+.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Ktorio_Closeables+.swift 3 | // JokesApp 4 | // 5 | // Created by Kurt Renzo Acosta on 7/10/21. 6 | // Copyright © 2021 Kurt. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import JokesShared 11 | 12 | extension Ktor_ioCloseable { 13 | func addToCloseables(_ viewModelWrapper: ViewModelWrapper) { 14 | viewModelWrapper.closeables.append(self) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /iosApp/JokesApp/utils/ViewModelWrapper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseObservableObject.swift 3 | // JokesApp 4 | // 5 | // Created by Kurt Renzo Acosta on 7/10/21. 6 | // Copyright © 2021 Kurt. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import JokesShared 11 | 12 | class ViewModelWrapper { 13 | var closeables: [Ktor_ioCloseable] = [] 14 | 15 | deinit { 16 | closeables.forEach { closeable in 17 | closeable.close() 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iosApp/JokesAppTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /iosApp/JokesAppTests/mppexampleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // mppexampleTests.swift 3 | // mppexampleTests 4 | // 5 | // Created by Kurt on 20/08/2019. 6 | // Copyright © 2019 Kurt. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import mppexample 11 | 12 | class mppexampleTests: XCTestCase { 13 | 14 | override func setUp() { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /iosApp/JokesAppUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /iosApp/JokesAppUITests/mppexampleUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // mppexampleUITests.swift 3 | // mppexampleUITests 4 | // 5 | // Created by Kurt on 20/08/2019. 6 | // Copyright © 2019 Kurt. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class mppexampleUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | 16 | // In UI tests it is usually best to stop immediately when a failure occurs. 17 | continueAfterFailure = false 18 | 19 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 20 | XCUIApplication().launch() 21 | 22 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 23 | } 24 | 25 | override func tearDown() { 26 | // Put teardown code here. This method is called after the invocation of each test method in the class. 27 | } 28 | 29 | func testExample() { 30 | // Use recording to get started writing UI tests. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /iosApp/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'JokesApp' do 5 | # Comment the next line if you don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for JokesApp 9 | pod "shared", :path => '../shared/shared.podspec' 10 | 11 | target 'JokesAppTests' do 12 | inherit! :search_paths 13 | # Pods for testing 14 | end 15 | 16 | target 'JokesAppUITests' do 17 | # Pods for testing 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /iosApp/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - shared (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - shared (from `../shared/shared.podspec`) 6 | 7 | EXTERNAL SOURCES: 8 | shared: 9 | :path: "../shared/shared.podspec" 10 | 11 | SPEC CHECKSUMS: 12 | shared: 6a8c228e921ebc8434e3098c58d15d5967261efb 13 | 14 | PODFILE CHECKSUM: dc93cd56d4e0c0842bdcf4355fe39df839148b86 15 | 16 | COCOAPODS: 1.10.0 17 | -------------------------------------------------------------------------------- /iosApp/Pods/Local Podspecs/common.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shared", 3 | "version": "1.0.0", 4 | "homepage": "Link to a Kotlin/Native module homepage", 5 | "source": { 6 | "git": "Not Published", 7 | "tag": "Cocoapods/shared/1.0.0" 8 | }, 9 | "authors": "", 10 | "license": "", 11 | "summary": "Shared module for Android and iOS", 12 | "static_framework": true, 13 | "vendored_frameworks": "build/cocoapods/framework/JokesShared.framework", 14 | "libraries": "c++", 15 | "module_name": "shared_umbrella", 16 | "pod_target_xcconfig": { 17 | "KOTLIN_TARGET[sdk=iphonesimulator*]": "ios_x64", 18 | "KOTLIN_TARGET[sdk=iphoneos*]": "ios_arm", 19 | "KOTLIN_TARGET[sdk=watchsimulator*]": "watchos_x64", 20 | "KOTLIN_TARGET[sdk=watchos*]": "watchos_arm", 21 | "KOTLIN_TARGET[sdk=appletvsimulator*]": "tvos_x64", 22 | "KOTLIN_TARGET[sdk=appletvos*]": "tvos_arm64", 23 | "KOTLIN_TARGET[sdk=macosx*]": "macos_x64" 24 | }, 25 | "script_phases": [ 26 | { 27 | "name": "Build shared", 28 | "execution_position": "before_compile", 29 | "shell_path": "/bin/sh", 30 | "script": " set -ev\n REPO_ROOT=\"$PODS_TARGET_SRCROOT\"\n \"$REPO_ROOT/../gradlew\" -p \"$REPO_ROOT\" :shared:syncFramework -Pkotlin.native.cocoapods.target=$KOTLIN_TARGET -Pkotlin.native.cocoapods.configuration=$CONFIGURATION -Pkotlin.native.cocoapods.cflags=\"$OTHER_CFLAGS\" -Pkotlin.native.cocoapods.paths.headers=\"$HEADER_SEARCH_PATHS\" -Pkotlin.native.cocoapods.paths.frameworks=\"$FRAMEWORK_SEARCH_PATHS\"\n" 31 | } 32 | ], 33 | "platforms": { 34 | "osx": null, 35 | "ios": null, 36 | "tvos": null, 37 | "watchos": null 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /iosApp/Pods/Local Podspecs/shared.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shared", 3 | "version": "1.0.0", 4 | "homepage": "Link to a Kotlin/Native module homepage", 5 | "source": { 6 | "git": "Not Published", 7 | "tag": "Cocoapods/shared/1.0.0" 8 | }, 9 | "authors": "", 10 | "license": "", 11 | "summary": "Shared module for Android and iOS", 12 | "static_framework": true, 13 | "vendored_frameworks": "build/cocoapods/framework/JokesShared.framework", 14 | "libraries": "c++", 15 | "module_name": "shared_umbrella", 16 | "pod_target_xcconfig": { 17 | "KOTLIN_TARGET[sdk=iphonesimulator*]": "ios_x64", 18 | "KOTLIN_TARGET[sdk=iphoneos*]": "ios_arm", 19 | "KOTLIN_TARGET[sdk=watchsimulator*]": "watchos_x64", 20 | "KOTLIN_TARGET[sdk=watchos*]": "watchos_arm", 21 | "KOTLIN_TARGET[sdk=appletvsimulator*]": "tvos_x64", 22 | "KOTLIN_TARGET[sdk=appletvos*]": "tvos_arm64", 23 | "KOTLIN_TARGET[sdk=macosx*]": "macos_x64" 24 | }, 25 | "script_phases": [ 26 | { 27 | "name": "Build shared", 28 | "execution_position": "before_compile", 29 | "shell_path": "/bin/sh", 30 | "script": " set -ev\n REPO_ROOT=\"$PODS_TARGET_SRCROOT\"\n \"$REPO_ROOT/../gradlew\" -p \"$REPO_ROOT\" :shared:syncFramework -Pkotlin.native.cocoapods.target=$KOTLIN_TARGET -Pkotlin.native.cocoapods.configuration=$CONFIGURATION -Pkotlin.native.cocoapods.cflags=\"$OTHER_CFLAGS\" -Pkotlin.native.cocoapods.paths.headers=\"$HEADER_SEARCH_PATHS\" -Pkotlin.native.cocoapods.paths.frameworks=\"$FRAMEWORK_SEARCH_PATHS\"\n" 31 | } 32 | ], 33 | "platforms": { 34 | "osx": null, 35 | "ios": null, 36 | "tvos": null, 37 | "watchos": null 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /iosApp/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - shared (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - shared (from `../shared/shared.podspec`) 6 | 7 | EXTERNAL SOURCES: 8 | shared: 9 | :path: "../shared/shared.podspec" 10 | 11 | SPEC CHECKSUMS: 12 | shared: 6a8c228e921ebc8434e3098c58d15d5967261efb 13 | 14 | PODFILE CHECKSUM: dc93cd56d4e0c0842bdcf4355fe39df839148b86 15 | 16 | COCOAPODS: 1.10.0 17 | -------------------------------------------------------------------------------- /iosApp/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | 8777C9F6889E59EFFD631D80AEE9048B /* shared */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = C12F82084A1D789106266CAAF7274FD2 /* Build configuration list for PBXAggregateTarget "shared" */; 13 | buildPhases = ( 14 | F2F266D90E96E94E3FEEA4EF908A1753 /* [CP-User] Build shared */, 15 | ); 16 | dependencies = ( 17 | ); 18 | name = shared; 19 | }; 20 | /* End PBXAggregateTarget section */ 21 | 22 | /* Begin PBXBuildFile section */ 23 | 027F93E3CA9E22C3CA075914B7D0C4C9 /* Pods-JokesApp-JokesAppUITests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D24D9C54B7358C05833BA7C9685B08D /* Pods-JokesApp-JokesAppUITests-dummy.m */; }; 24 | 12F516D65DFB41612C8C925939DA7FF1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 25 | 2B4A37258B29E8296E90F98D077A53A6 /* Pods-JokesApp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F5168DE93CF4D0D86BD7541580DA440 /* Pods-JokesApp-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26 | 2D143CFFE9B756833FDC9674A9C79CF3 /* Pods-JokesApp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F9E932BD27DE635293E4F76C358F30F /* Pods-JokesApp-dummy.m */; }; 27 | 301BF5351F9E119DABF07E3F129E3D8E /* Pods-JokesAppTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 871F59F46454680A8CFE720D087964C0 /* Pods-JokesAppTests-dummy.m */; }; 28 | 6F659E02FC0FD7F6055FF5A637786A63 /* Pods-JokesAppTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = AF704D2A051598612D47A1520F2B7E93 /* Pods-JokesAppTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | 99E3409392B848C7212D8C430D64F442 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 30 | BDE91AD8BF3F5A589E2E6AC42C96BB86 /* Pods-JokesApp-JokesAppUITests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 91525EA385650B3A88BF93275D25A557 /* Pods-JokesApp-JokesAppUITests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 31 | D94FAAC57B4FF1AE0AAD2C7F7D94AABA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXContainerItemProxy section */ 35 | 5C35E5CCA37612CC1FD9B7C2EF0579E6 /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; 38 | proxyType = 1; 39 | remoteGlobalIDString = E80DDCE0F69CF2F5AA0E0142C25F8F35; 40 | remoteInfo = "Pods-JokesApp"; 41 | }; 42 | 8E9341334BA49D35ECACC07DAD7083E1 /* PBXContainerItemProxy */ = { 43 | isa = PBXContainerItemProxy; 44 | containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; 45 | proxyType = 1; 46 | remoteGlobalIDString = 8777C9F6889E59EFFD631D80AEE9048B; 47 | remoteInfo = shared; 48 | }; 49 | DAD4CFB792D7C4AD1ADAFAB62A721667 /* PBXContainerItemProxy */ = { 50 | isa = PBXContainerItemProxy; 51 | containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; 52 | proxyType = 1; 53 | remoteGlobalIDString = 8777C9F6889E59EFFD631D80AEE9048B; 54 | remoteInfo = shared; 55 | }; 56 | /* End PBXContainerItemProxy section */ 57 | 58 | /* Begin PBXFileReference section */ 59 | 0B4417E0349CCD73ABE6F1A1B2EFF969 /* Pods-JokesApp-JokesAppUITests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-JokesApp-JokesAppUITests.modulemap"; sourceTree = ""; }; 60 | 0EA4D094B745A8A91EA03B7CF6CD4E39 /* Pods-JokesApp-JokesAppUITests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-JokesApp-JokesAppUITests-acknowledgements.plist"; sourceTree = ""; }; 61 | 14F3E0BE1549710890F51EB8800CBDE3 /* Pods-JokesApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-JokesApp.release.xcconfig"; sourceTree = ""; }; 62 | 2E0A6D0835A06C8035F27EC64FA3D241 /* Pods-JokesAppTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-JokesAppTests-Info.plist"; sourceTree = ""; }; 63 | 35548E3BD8DA30925E8FE97E67B84868 /* shared.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = shared.release.xcconfig; sourceTree = ""; }; 64 | 4A91223836C7F2614DDF49F3EA74DBD1 /* Pods-JokesAppTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-JokesAppTests-acknowledgements.markdown"; sourceTree = ""; }; 65 | 5493CC0BF75CDFB1046A1061E754C137 /* Pods-JokesApp-JokesAppUITests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-JokesApp-JokesAppUITests-Info.plist"; sourceTree = ""; }; 66 | 61703E4C99B30702491484BAF9E8E17C /* Pods-JokesApp-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-JokesApp-acknowledgements.plist"; sourceTree = ""; }; 67 | 63C3C8F62CD1AF365B0FB82BEBFC65D8 /* Pods-JokesApp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-JokesApp.modulemap"; sourceTree = ""; }; 68 | 656FF9BB449B7EEA04C53643815CBBBC /* Pods-JokesApp-JokesAppUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-JokesApp-JokesAppUITests.release.xcconfig"; sourceTree = ""; }; 69 | 708393D972AFAF28C3EA72D57A8DCD16 /* Pods-JokesAppTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-JokesAppTests.release.xcconfig"; sourceTree = ""; }; 70 | 723411B8F06E13DA628DCA9BBC50B077 /* Pods-JokesAppTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-JokesAppTests.debug.xcconfig"; sourceTree = ""; }; 71 | 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 72 | 777F4D29492132AD0A735D515DBDAFF1 /* Pods-JokesAppTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-JokesAppTests.modulemap"; sourceTree = ""; }; 73 | 7AEBE5C1AF8B78390308215A9533F89A /* Pods-JokesApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-JokesApp.debug.xcconfig"; sourceTree = ""; }; 74 | 7FB8CC0F4AE67620CD6A2E4F88475FCC /* Pods-JokesApp-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-JokesApp-acknowledgements.markdown"; sourceTree = ""; }; 75 | 83A24B950A0EB13DC88DC0EC699DA9BF /* Pods-JokesAppTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-JokesAppTests-acknowledgements.plist"; sourceTree = ""; }; 76 | 871F59F46454680A8CFE720D087964C0 /* Pods-JokesAppTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-JokesAppTests-dummy.m"; sourceTree = ""; }; 77 | 875FF74BD6B97285B0196B484C60140E /* JokesShared.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JokesShared.framework; path = build/cocoapods/framework/JokesShared.framework; sourceTree = ""; }; 78 | 91525EA385650B3A88BF93275D25A557 /* Pods-JokesApp-JokesAppUITests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-JokesApp-JokesAppUITests-umbrella.h"; sourceTree = ""; }; 79 | 95B09EA82E7AF9ACCCCAF3E55C859116 /* shared.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = shared.debug.xcconfig; sourceTree = ""; }; 80 | 9D24D9C54B7358C05833BA7C9685B08D /* Pods-JokesApp-JokesAppUITests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-JokesApp-JokesAppUITests-dummy.m"; sourceTree = ""; }; 81 | 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 82 | 9F5168DE93CF4D0D86BD7541580DA440 /* Pods-JokesApp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-JokesApp-umbrella.h"; sourceTree = ""; }; 83 | 9F9E932BD27DE635293E4F76C358F30F /* Pods-JokesApp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-JokesApp-dummy.m"; sourceTree = ""; }; 84 | A8469256EDDC39F53B49B53F73C4067F /* Pods-JokesApp-JokesAppUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-JokesApp-JokesAppUITests.debug.xcconfig"; sourceTree = ""; }; 85 | AF1F6302B5E0DC60C110AB6094FD5541 /* Pods_JokesApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_JokesApp.framework; path = "Pods-JokesApp.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 86 | AF704D2A051598612D47A1520F2B7E93 /* Pods-JokesAppTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-JokesAppTests-umbrella.h"; sourceTree = ""; }; 87 | BB5BD0E9DE070D702505462BA8003187 /* Pods-JokesApp-JokesAppUITests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-JokesApp-JokesAppUITests-acknowledgements.markdown"; sourceTree = ""; }; 88 | CC079A1E17692234FDF67AFF36C34346 /* Pods-JokesApp-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-JokesApp-Info.plist"; sourceTree = ""; }; 89 | D00B5C016EB2EF5F08A1BC5910F60065 /* Pods_JokesApp_JokesAppUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_JokesApp_JokesAppUITests.framework; path = "Pods-JokesApp-JokesAppUITests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | DE0501490A6A01714DA9D4854B9C007A /* Pods_JokesAppTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_JokesAppTests.framework; path = "Pods-JokesAppTests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 91 | FB1BF8BE937671FB0F330C2D28634477 /* shared.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = shared.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 92 | /* End PBXFileReference section */ 93 | 94 | /* Begin PBXFrameworksBuildPhase section */ 95 | 15BBB4421959C87B555FB870FFD26F8E /* Frameworks */ = { 96 | isa = PBXFrameworksBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | D94FAAC57B4FF1AE0AAD2C7F7D94AABA /* Foundation.framework in Frameworks */, 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | 29898C450058F2753D1C63F4992300BE /* Frameworks */ = { 104 | isa = PBXFrameworksBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | 12F516D65DFB41612C8C925939DA7FF1 /* Foundation.framework in Frameworks */, 108 | ); 109 | runOnlyForDeploymentPostprocessing = 0; 110 | }; 111 | B7EB58C0B4FF47A8CBA9A4865183F26E /* Frameworks */ = { 112 | isa = PBXFrameworksBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | 99E3409392B848C7212D8C430D64F442 /* Foundation.framework in Frameworks */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | /* End PBXFrameworksBuildPhase section */ 120 | 121 | /* Begin PBXGroup section */ 122 | 193FE2F0F3FF64C4133F563BCB35279F /* Pods-JokesAppTests */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 777F4D29492132AD0A735D515DBDAFF1 /* Pods-JokesAppTests.modulemap */, 126 | 4A91223836C7F2614DDF49F3EA74DBD1 /* Pods-JokesAppTests-acknowledgements.markdown */, 127 | 83A24B950A0EB13DC88DC0EC699DA9BF /* Pods-JokesAppTests-acknowledgements.plist */, 128 | 871F59F46454680A8CFE720D087964C0 /* Pods-JokesAppTests-dummy.m */, 129 | 2E0A6D0835A06C8035F27EC64FA3D241 /* Pods-JokesAppTests-Info.plist */, 130 | AF704D2A051598612D47A1520F2B7E93 /* Pods-JokesAppTests-umbrella.h */, 131 | 723411B8F06E13DA628DCA9BBC50B077 /* Pods-JokesAppTests.debug.xcconfig */, 132 | 708393D972AFAF28C3EA72D57A8DCD16 /* Pods-JokesAppTests.release.xcconfig */, 133 | ); 134 | name = "Pods-JokesAppTests"; 135 | path = "Target Support Files/Pods-JokesAppTests"; 136 | sourceTree = ""; 137 | }; 138 | 313FE5FE915A4A924C55AAC02A910D61 /* Development Pods */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | EEF3277DCE2E4B31CF76A57AB68C2BA1 /* shared */, 142 | ); 143 | name = "Development Pods"; 144 | sourceTree = ""; 145 | }; 146 | 4CF2ADC2D82AF02E4803178C51C24EFE /* Pods-JokesApp */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 63C3C8F62CD1AF365B0FB82BEBFC65D8 /* Pods-JokesApp.modulemap */, 150 | 7FB8CC0F4AE67620CD6A2E4F88475FCC /* Pods-JokesApp-acknowledgements.markdown */, 151 | 61703E4C99B30702491484BAF9E8E17C /* Pods-JokesApp-acknowledgements.plist */, 152 | 9F9E932BD27DE635293E4F76C358F30F /* Pods-JokesApp-dummy.m */, 153 | CC079A1E17692234FDF67AFF36C34346 /* Pods-JokesApp-Info.plist */, 154 | 9F5168DE93CF4D0D86BD7541580DA440 /* Pods-JokesApp-umbrella.h */, 155 | 7AEBE5C1AF8B78390308215A9533F89A /* Pods-JokesApp.debug.xcconfig */, 156 | 14F3E0BE1549710890F51EB8800CBDE3 /* Pods-JokesApp.release.xcconfig */, 157 | ); 158 | name = "Pods-JokesApp"; 159 | path = "Target Support Files/Pods-JokesApp"; 160 | sourceTree = ""; 161 | }; 162 | 569B56E5B05425CAE32676C6049DC8CB /* Pod */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | FB1BF8BE937671FB0F330C2D28634477 /* shared.podspec */, 166 | ); 167 | name = Pod; 168 | sourceTree = ""; 169 | }; 170 | 578452D2E740E91742655AC8F1636D1F /* iOS */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */, 174 | ); 175 | name = iOS; 176 | sourceTree = ""; 177 | }; 178 | 5CB66AAACA3977B45E9869C360E9F289 /* Support Files */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 95B09EA82E7AF9ACCCCAF3E55C859116 /* shared.debug.xcconfig */, 182 | 35548E3BD8DA30925E8FE97E67B84868 /* shared.release.xcconfig */, 183 | ); 184 | name = "Support Files"; 185 | path = "../iosApp/Pods/Target Support Files/shared"; 186 | sourceTree = ""; 187 | }; 188 | 79517121B45B4BFFD0F53BB5F22ADDF1 /* Targets Support Files */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | 4CF2ADC2D82AF02E4803178C51C24EFE /* Pods-JokesApp */, 192 | B2082E4D40DBA1C122A5505D1C80569F /* Pods-JokesApp-JokesAppUITests */, 193 | 193FE2F0F3FF64C4133F563BCB35279F /* Pods-JokesAppTests */, 194 | ); 195 | name = "Targets Support Files"; 196 | sourceTree = ""; 197 | }; 198 | 8C53BBB736146D7BCB3A8D3402607B37 /* Frameworks */ = { 199 | isa = PBXGroup; 200 | children = ( 201 | 875FF74BD6B97285B0196B484C60140E /* JokesShared.framework */, 202 | ); 203 | name = Frameworks; 204 | sourceTree = ""; 205 | }; 206 | B2082E4D40DBA1C122A5505D1C80569F /* Pods-JokesApp-JokesAppUITests */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | 0B4417E0349CCD73ABE6F1A1B2EFF969 /* Pods-JokesApp-JokesAppUITests.modulemap */, 210 | BB5BD0E9DE070D702505462BA8003187 /* Pods-JokesApp-JokesAppUITests-acknowledgements.markdown */, 211 | 0EA4D094B745A8A91EA03B7CF6CD4E39 /* Pods-JokesApp-JokesAppUITests-acknowledgements.plist */, 212 | 9D24D9C54B7358C05833BA7C9685B08D /* Pods-JokesApp-JokesAppUITests-dummy.m */, 213 | 5493CC0BF75CDFB1046A1061E754C137 /* Pods-JokesApp-JokesAppUITests-Info.plist */, 214 | 91525EA385650B3A88BF93275D25A557 /* Pods-JokesApp-JokesAppUITests-umbrella.h */, 215 | A8469256EDDC39F53B49B53F73C4067F /* Pods-JokesApp-JokesAppUITests.debug.xcconfig */, 216 | 656FF9BB449B7EEA04C53643815CBBBC /* Pods-JokesApp-JokesAppUITests.release.xcconfig */, 217 | ); 218 | name = "Pods-JokesApp-JokesAppUITests"; 219 | path = "Target Support Files/Pods-JokesApp-JokesAppUITests"; 220 | sourceTree = ""; 221 | }; 222 | CF1408CF629C7361332E53B88F7BD30C = { 223 | isa = PBXGroup; 224 | children = ( 225 | 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, 226 | 313FE5FE915A4A924C55AAC02A910D61 /* Development Pods */, 227 | D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, 228 | DAFB94CBB8898A66111384412493CC03 /* Products */, 229 | 79517121B45B4BFFD0F53BB5F22ADDF1 /* Targets Support Files */, 230 | ); 231 | sourceTree = ""; 232 | }; 233 | D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { 234 | isa = PBXGroup; 235 | children = ( 236 | 578452D2E740E91742655AC8F1636D1F /* iOS */, 237 | ); 238 | name = Frameworks; 239 | sourceTree = ""; 240 | }; 241 | DAFB94CBB8898A66111384412493CC03 /* Products */ = { 242 | isa = PBXGroup; 243 | children = ( 244 | AF1F6302B5E0DC60C110AB6094FD5541 /* Pods_JokesApp.framework */, 245 | D00B5C016EB2EF5F08A1BC5910F60065 /* Pods_JokesApp_JokesAppUITests.framework */, 246 | DE0501490A6A01714DA9D4854B9C007A /* Pods_JokesAppTests.framework */, 247 | ); 248 | name = Products; 249 | sourceTree = ""; 250 | }; 251 | EEF3277DCE2E4B31CF76A57AB68C2BA1 /* shared */ = { 252 | isa = PBXGroup; 253 | children = ( 254 | 8C53BBB736146D7BCB3A8D3402607B37 /* Frameworks */, 255 | 569B56E5B05425CAE32676C6049DC8CB /* Pod */, 256 | 5CB66AAACA3977B45E9869C360E9F289 /* Support Files */, 257 | ); 258 | name = shared; 259 | path = ../../shared; 260 | sourceTree = ""; 261 | }; 262 | /* End PBXGroup section */ 263 | 264 | /* Begin PBXHeadersBuildPhase section */ 265 | 494DDD1123D6CBA58FA4761EC3AEADF7 /* Headers */ = { 266 | isa = PBXHeadersBuildPhase; 267 | buildActionMask = 2147483647; 268 | files = ( 269 | 2B4A37258B29E8296E90F98D077A53A6 /* Pods-JokesApp-umbrella.h in Headers */, 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | D39A05971BC71C9851711BBF0463EAC5 /* Headers */ = { 274 | isa = PBXHeadersBuildPhase; 275 | buildActionMask = 2147483647; 276 | files = ( 277 | BDE91AD8BF3F5A589E2E6AC42C96BB86 /* Pods-JokesApp-JokesAppUITests-umbrella.h in Headers */, 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | EAB3F72C43D69BC21AC35F4D47AE759F /* Headers */ = { 282 | isa = PBXHeadersBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | 6F659E02FC0FD7F6055FF5A637786A63 /* Pods-JokesAppTests-umbrella.h in Headers */, 286 | ); 287 | runOnlyForDeploymentPostprocessing = 0; 288 | }; 289 | /* End PBXHeadersBuildPhase section */ 290 | 291 | /* Begin PBXNativeTarget section */ 292 | 69324FB9C937C29B0F347EBA146BEE9B /* Pods-JokesAppTests */ = { 293 | isa = PBXNativeTarget; 294 | buildConfigurationList = A4E6ED1E049DD76E34F5B81B6948CB67 /* Build configuration list for PBXNativeTarget "Pods-JokesAppTests" */; 295 | buildPhases = ( 296 | EAB3F72C43D69BC21AC35F4D47AE759F /* Headers */, 297 | F06AA4DBCF10FBD77CE304DDD8D2D1E5 /* Sources */, 298 | B7EB58C0B4FF47A8CBA9A4865183F26E /* Frameworks */, 299 | 245AE7B239D74BB6093B9F4028EEF0CA /* Resources */, 300 | ); 301 | buildRules = ( 302 | ); 303 | dependencies = ( 304 | A39D20AA079A0461DD415D3CED292B50 /* PBXTargetDependency */, 305 | ); 306 | name = "Pods-JokesAppTests"; 307 | productName = "Pods-JokesAppTests"; 308 | productReference = DE0501490A6A01714DA9D4854B9C007A /* Pods_JokesAppTests.framework */; 309 | productType = "com.apple.product-type.framework"; 310 | }; 311 | 8F3C77D4235F871E1EAC0F613E937E0D /* Pods-JokesApp-JokesAppUITests */ = { 312 | isa = PBXNativeTarget; 313 | buildConfigurationList = 7F8C885627680300F1E6F98C1FB57356 /* Build configuration list for PBXNativeTarget "Pods-JokesApp-JokesAppUITests" */; 314 | buildPhases = ( 315 | D39A05971BC71C9851711BBF0463EAC5 /* Headers */, 316 | FC1330B502D2B2401B5CD9FB80A086B9 /* Sources */, 317 | 15BBB4421959C87B555FB870FFD26F8E /* Frameworks */, 318 | 10E143E4C96EBC21FAA5A497605A8C0C /* Resources */, 319 | ); 320 | buildRules = ( 321 | ); 322 | dependencies = ( 323 | 2B4D63AAFDEE95B63220614BD54CDC80 /* PBXTargetDependency */, 324 | ); 325 | name = "Pods-JokesApp-JokesAppUITests"; 326 | productName = "Pods-JokesApp-JokesAppUITests"; 327 | productReference = D00B5C016EB2EF5F08A1BC5910F60065 /* Pods_JokesApp_JokesAppUITests.framework */; 328 | productType = "com.apple.product-type.framework"; 329 | }; 330 | E80DDCE0F69CF2F5AA0E0142C25F8F35 /* Pods-JokesApp */ = { 331 | isa = PBXNativeTarget; 332 | buildConfigurationList = F56F7B9E213404FCC59ABADB8EFBA9F4 /* Build configuration list for PBXNativeTarget "Pods-JokesApp" */; 333 | buildPhases = ( 334 | 494DDD1123D6CBA58FA4761EC3AEADF7 /* Headers */, 335 | 693F8EF11D35D04A8EC1DD42B9EC8643 /* Sources */, 336 | 29898C450058F2753D1C63F4992300BE /* Frameworks */, 337 | 57464F4FFB9B338B870D4CA1156D17F4 /* Resources */, 338 | ); 339 | buildRules = ( 340 | ); 341 | dependencies = ( 342 | 14E1F22EE3441634088B6A1FB4D401A0 /* PBXTargetDependency */, 343 | ); 344 | name = "Pods-JokesApp"; 345 | productName = "Pods-JokesApp"; 346 | productReference = AF1F6302B5E0DC60C110AB6094FD5541 /* Pods_JokesApp.framework */; 347 | productType = "com.apple.product-type.framework"; 348 | }; 349 | /* End PBXNativeTarget section */ 350 | 351 | /* Begin PBXProject section */ 352 | BFDFE7DC352907FC980B868725387E98 /* Project object */ = { 353 | isa = PBXProject; 354 | attributes = { 355 | LastSwiftUpdateCheck = 1100; 356 | LastUpgradeCheck = 1100; 357 | }; 358 | buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; 359 | compatibilityVersion = "Xcode 9.3"; 360 | developmentRegion = en; 361 | hasScannedForEncodings = 0; 362 | knownRegions = ( 363 | en, 364 | Base, 365 | ); 366 | mainGroup = CF1408CF629C7361332E53B88F7BD30C; 367 | productRefGroup = DAFB94CBB8898A66111384412493CC03 /* Products */; 368 | projectDirPath = ""; 369 | projectRoot = ""; 370 | targets = ( 371 | E80DDCE0F69CF2F5AA0E0142C25F8F35 /* Pods-JokesApp */, 372 | 8F3C77D4235F871E1EAC0F613E937E0D /* Pods-JokesApp-JokesAppUITests */, 373 | 69324FB9C937C29B0F347EBA146BEE9B /* Pods-JokesAppTests */, 374 | 8777C9F6889E59EFFD631D80AEE9048B /* shared */, 375 | ); 376 | }; 377 | /* End PBXProject section */ 378 | 379 | /* Begin PBXResourcesBuildPhase section */ 380 | 10E143E4C96EBC21FAA5A497605A8C0C /* Resources */ = { 381 | isa = PBXResourcesBuildPhase; 382 | buildActionMask = 2147483647; 383 | files = ( 384 | ); 385 | runOnlyForDeploymentPostprocessing = 0; 386 | }; 387 | 245AE7B239D74BB6093B9F4028EEF0CA /* Resources */ = { 388 | isa = PBXResourcesBuildPhase; 389 | buildActionMask = 2147483647; 390 | files = ( 391 | ); 392 | runOnlyForDeploymentPostprocessing = 0; 393 | }; 394 | 57464F4FFB9B338B870D4CA1156D17F4 /* Resources */ = { 395 | isa = PBXResourcesBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | ); 399 | runOnlyForDeploymentPostprocessing = 0; 400 | }; 401 | /* End PBXResourcesBuildPhase section */ 402 | 403 | /* Begin PBXShellScriptBuildPhase section */ 404 | F2F266D90E96E94E3FEEA4EF908A1753 /* [CP-User] Build shared */ = { 405 | isa = PBXShellScriptBuildPhase; 406 | buildActionMask = 2147483647; 407 | files = ( 408 | ); 409 | name = "[CP-User] Build shared"; 410 | runOnlyForDeploymentPostprocessing = 0; 411 | shellPath = /bin/sh; 412 | shellScript = " set -ev\n REPO_ROOT=\"$PODS_TARGET_SRCROOT\"\n \"$REPO_ROOT/../gradlew\" -p \"$REPO_ROOT\" :shared:syncFramework -Pkotlin.native.cocoapods.target=$KOTLIN_TARGET -Pkotlin.native.cocoapods.configuration=$CONFIGURATION -Pkotlin.native.cocoapods.cflags=\"$OTHER_CFLAGS\" -Pkotlin.native.cocoapods.paths.headers=\"$HEADER_SEARCH_PATHS\" -Pkotlin.native.cocoapods.paths.frameworks=\"$FRAMEWORK_SEARCH_PATHS\"\n"; 413 | }; 414 | /* End PBXShellScriptBuildPhase section */ 415 | 416 | /* Begin PBXSourcesBuildPhase section */ 417 | 693F8EF11D35D04A8EC1DD42B9EC8643 /* Sources */ = { 418 | isa = PBXSourcesBuildPhase; 419 | buildActionMask = 2147483647; 420 | files = ( 421 | 2D143CFFE9B756833FDC9674A9C79CF3 /* Pods-JokesApp-dummy.m in Sources */, 422 | ); 423 | runOnlyForDeploymentPostprocessing = 0; 424 | }; 425 | F06AA4DBCF10FBD77CE304DDD8D2D1E5 /* Sources */ = { 426 | isa = PBXSourcesBuildPhase; 427 | buildActionMask = 2147483647; 428 | files = ( 429 | 301BF5351F9E119DABF07E3F129E3D8E /* Pods-JokesAppTests-dummy.m in Sources */, 430 | ); 431 | runOnlyForDeploymentPostprocessing = 0; 432 | }; 433 | FC1330B502D2B2401B5CD9FB80A086B9 /* Sources */ = { 434 | isa = PBXSourcesBuildPhase; 435 | buildActionMask = 2147483647; 436 | files = ( 437 | 027F93E3CA9E22C3CA075914B7D0C4C9 /* Pods-JokesApp-JokesAppUITests-dummy.m in Sources */, 438 | ); 439 | runOnlyForDeploymentPostprocessing = 0; 440 | }; 441 | /* End PBXSourcesBuildPhase section */ 442 | 443 | /* Begin PBXTargetDependency section */ 444 | 14E1F22EE3441634088B6A1FB4D401A0 /* PBXTargetDependency */ = { 445 | isa = PBXTargetDependency; 446 | name = shared; 447 | target = 8777C9F6889E59EFFD631D80AEE9048B /* shared */; 448 | targetProxy = DAD4CFB792D7C4AD1ADAFAB62A721667 /* PBXContainerItemProxy */; 449 | }; 450 | 2B4D63AAFDEE95B63220614BD54CDC80 /* PBXTargetDependency */ = { 451 | isa = PBXTargetDependency; 452 | name = shared; 453 | target = 8777C9F6889E59EFFD631D80AEE9048B /* shared */; 454 | targetProxy = 8E9341334BA49D35ECACC07DAD7083E1 /* PBXContainerItemProxy */; 455 | }; 456 | A39D20AA079A0461DD415D3CED292B50 /* PBXTargetDependency */ = { 457 | isa = PBXTargetDependency; 458 | name = "Pods-JokesApp"; 459 | target = E80DDCE0F69CF2F5AA0E0142C25F8F35 /* Pods-JokesApp */; 460 | targetProxy = 5C35E5CCA37612CC1FD9B7C2EF0579E6 /* PBXContainerItemProxy */; 461 | }; 462 | /* End PBXTargetDependency section */ 463 | 464 | /* Begin XCBuildConfiguration section */ 465 | 16A66CB8339521257E84A7FBE66B934F /* Debug */ = { 466 | isa = XCBuildConfiguration; 467 | baseConfigurationReference = A8469256EDDC39F53B49B53F73C4067F /* Pods-JokesApp-JokesAppUITests.debug.xcconfig */; 468 | buildSettings = { 469 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 470 | CLANG_ENABLE_OBJC_WEAK = NO; 471 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 472 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 473 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 474 | CURRENT_PROJECT_VERSION = 1; 475 | DEFINES_MODULE = YES; 476 | DYLIB_COMPATIBILITY_VERSION = 1; 477 | DYLIB_CURRENT_VERSION = 1; 478 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 479 | INFOPLIST_FILE = "Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests-Info.plist"; 480 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 481 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 482 | LD_RUNPATH_SEARCH_PATHS = ( 483 | "$(inherited)", 484 | "@executable_path/Frameworks", 485 | "@loader_path/Frameworks", 486 | ); 487 | MACH_O_TYPE = staticlib; 488 | MODULEMAP_FILE = "Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests.modulemap"; 489 | OTHER_LDFLAGS = ""; 490 | OTHER_LIBTOOLFLAGS = ""; 491 | PODS_ROOT = "$(SRCROOT)"; 492 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 493 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 494 | SDKROOT = iphoneos; 495 | SKIP_INSTALL = YES; 496 | TARGETED_DEVICE_FAMILY = "1,2"; 497 | VERSIONING_SYSTEM = "apple-generic"; 498 | VERSION_INFO_PREFIX = ""; 499 | }; 500 | name = Debug; 501 | }; 502 | 227B446DBBD8A4398C780CCEC3A058D7 /* Release */ = { 503 | isa = XCBuildConfiguration; 504 | baseConfigurationReference = 35548E3BD8DA30925E8FE97E67B84868 /* shared.release.xcconfig */; 505 | buildSettings = { 506 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 507 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 508 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 509 | LD_RUNPATH_SEARCH_PATHS = ( 510 | "$(inherited)", 511 | "@executable_path/Frameworks", 512 | ); 513 | SDKROOT = iphoneos; 514 | TARGETED_DEVICE_FAMILY = "1,2"; 515 | VALIDATE_PRODUCT = YES; 516 | }; 517 | name = Release; 518 | }; 519 | 4BC7450F9457737EE3E637BA155B56F7 /* Debug */ = { 520 | isa = XCBuildConfiguration; 521 | buildSettings = { 522 | ALWAYS_SEARCH_USER_PATHS = NO; 523 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 524 | CLANG_ANALYZER_NONNULL = YES; 525 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 526 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 527 | CLANG_CXX_LIBRARY = "libc++"; 528 | CLANG_ENABLE_MODULES = YES; 529 | CLANG_ENABLE_OBJC_ARC = YES; 530 | CLANG_ENABLE_OBJC_WEAK = YES; 531 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 532 | CLANG_WARN_BOOL_CONVERSION = YES; 533 | CLANG_WARN_COMMA = YES; 534 | CLANG_WARN_CONSTANT_CONVERSION = YES; 535 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 536 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 537 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 538 | CLANG_WARN_EMPTY_BODY = YES; 539 | CLANG_WARN_ENUM_CONVERSION = YES; 540 | CLANG_WARN_INFINITE_RECURSION = YES; 541 | CLANG_WARN_INT_CONVERSION = YES; 542 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 543 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 544 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 545 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 546 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 547 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 548 | CLANG_WARN_STRICT_PROTOTYPES = YES; 549 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 550 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 551 | CLANG_WARN_UNREACHABLE_CODE = YES; 552 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 553 | COPY_PHASE_STRIP = NO; 554 | DEBUG_INFORMATION_FORMAT = dwarf; 555 | ENABLE_STRICT_OBJC_MSGSEND = YES; 556 | ENABLE_TESTABILITY = YES; 557 | GCC_C_LANGUAGE_STANDARD = gnu11; 558 | GCC_DYNAMIC_NO_PIC = NO; 559 | GCC_NO_COMMON_BLOCKS = YES; 560 | GCC_OPTIMIZATION_LEVEL = 0; 561 | GCC_PREPROCESSOR_DEFINITIONS = ( 562 | "POD_CONFIGURATION_DEBUG=1", 563 | "DEBUG=1", 564 | "$(inherited)", 565 | ); 566 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 567 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 568 | GCC_WARN_UNDECLARED_SELECTOR = YES; 569 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 570 | GCC_WARN_UNUSED_FUNCTION = YES; 571 | GCC_WARN_UNUSED_VARIABLE = YES; 572 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 573 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 574 | MTL_FAST_MATH = YES; 575 | ONLY_ACTIVE_ARCH = YES; 576 | PRODUCT_NAME = "$(TARGET_NAME)"; 577 | STRIP_INSTALLED_PRODUCT = NO; 578 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 579 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 580 | SWIFT_VERSION = 5.0; 581 | SYMROOT = "${SRCROOT}/../build"; 582 | }; 583 | name = Debug; 584 | }; 585 | 4FAC2C9C8C4A06122802ADD9FD921FBB /* Debug */ = { 586 | isa = XCBuildConfiguration; 587 | baseConfigurationReference = 723411B8F06E13DA628DCA9BBC50B077 /* Pods-JokesAppTests.debug.xcconfig */; 588 | buildSettings = { 589 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 590 | CLANG_ENABLE_OBJC_WEAK = NO; 591 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 592 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 593 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 594 | CURRENT_PROJECT_VERSION = 1; 595 | DEFINES_MODULE = YES; 596 | DYLIB_COMPATIBILITY_VERSION = 1; 597 | DYLIB_CURRENT_VERSION = 1; 598 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 599 | INFOPLIST_FILE = "Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests-Info.plist"; 600 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 601 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 602 | LD_RUNPATH_SEARCH_PATHS = ( 603 | "$(inherited)", 604 | "@executable_path/Frameworks", 605 | "@loader_path/Frameworks", 606 | ); 607 | MACH_O_TYPE = staticlib; 608 | MODULEMAP_FILE = "Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests.modulemap"; 609 | OTHER_LDFLAGS = ""; 610 | OTHER_LIBTOOLFLAGS = ""; 611 | PODS_ROOT = "$(SRCROOT)"; 612 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 613 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 614 | SDKROOT = iphoneos; 615 | SKIP_INSTALL = YES; 616 | TARGETED_DEVICE_FAMILY = "1,2"; 617 | VERSIONING_SYSTEM = "apple-generic"; 618 | VERSION_INFO_PREFIX = ""; 619 | }; 620 | name = Debug; 621 | }; 622 | 52AFFB3B12CA28E60E0860748C36F10F /* Debug */ = { 623 | isa = XCBuildConfiguration; 624 | baseConfigurationReference = 7AEBE5C1AF8B78390308215A9533F89A /* Pods-JokesApp.debug.xcconfig */; 625 | buildSettings = { 626 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 627 | CLANG_ENABLE_OBJC_WEAK = NO; 628 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 629 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 630 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 631 | CURRENT_PROJECT_VERSION = 1; 632 | DEFINES_MODULE = YES; 633 | DYLIB_COMPATIBILITY_VERSION = 1; 634 | DYLIB_CURRENT_VERSION = 1; 635 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 636 | INFOPLIST_FILE = "Target Support Files/Pods-JokesApp/Pods-JokesApp-Info.plist"; 637 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 638 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 639 | LD_RUNPATH_SEARCH_PATHS = ( 640 | "$(inherited)", 641 | "@executable_path/Frameworks", 642 | "@loader_path/Frameworks", 643 | ); 644 | MACH_O_TYPE = staticlib; 645 | MODULEMAP_FILE = "Target Support Files/Pods-JokesApp/Pods-JokesApp.modulemap"; 646 | OTHER_LDFLAGS = ""; 647 | OTHER_LIBTOOLFLAGS = ""; 648 | PODS_ROOT = "$(SRCROOT)"; 649 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 650 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 651 | SDKROOT = iphoneos; 652 | SKIP_INSTALL = YES; 653 | TARGETED_DEVICE_FAMILY = "1,2"; 654 | VERSIONING_SYSTEM = "apple-generic"; 655 | VERSION_INFO_PREFIX = ""; 656 | }; 657 | name = Debug; 658 | }; 659 | 7DF8CE9EF69CDEDE8B1B025D88D9D322 /* Release */ = { 660 | isa = XCBuildConfiguration; 661 | baseConfigurationReference = 656FF9BB449B7EEA04C53643815CBBBC /* Pods-JokesApp-JokesAppUITests.release.xcconfig */; 662 | buildSettings = { 663 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 664 | CLANG_ENABLE_OBJC_WEAK = NO; 665 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 666 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 667 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 668 | CURRENT_PROJECT_VERSION = 1; 669 | DEFINES_MODULE = YES; 670 | DYLIB_COMPATIBILITY_VERSION = 1; 671 | DYLIB_CURRENT_VERSION = 1; 672 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 673 | INFOPLIST_FILE = "Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests-Info.plist"; 674 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 675 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 676 | LD_RUNPATH_SEARCH_PATHS = ( 677 | "$(inherited)", 678 | "@executable_path/Frameworks", 679 | "@loader_path/Frameworks", 680 | ); 681 | MACH_O_TYPE = staticlib; 682 | MODULEMAP_FILE = "Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests.modulemap"; 683 | OTHER_LDFLAGS = ""; 684 | OTHER_LIBTOOLFLAGS = ""; 685 | PODS_ROOT = "$(SRCROOT)"; 686 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 687 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 688 | SDKROOT = iphoneos; 689 | SKIP_INSTALL = YES; 690 | TARGETED_DEVICE_FAMILY = "1,2"; 691 | VALIDATE_PRODUCT = YES; 692 | VERSIONING_SYSTEM = "apple-generic"; 693 | VERSION_INFO_PREFIX = ""; 694 | }; 695 | name = Release; 696 | }; 697 | 8B5A46FF8D3C1289CDEE3BAFACABCD2A /* Release */ = { 698 | isa = XCBuildConfiguration; 699 | buildSettings = { 700 | ALWAYS_SEARCH_USER_PATHS = NO; 701 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 702 | CLANG_ANALYZER_NONNULL = YES; 703 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 704 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 705 | CLANG_CXX_LIBRARY = "libc++"; 706 | CLANG_ENABLE_MODULES = YES; 707 | CLANG_ENABLE_OBJC_ARC = YES; 708 | CLANG_ENABLE_OBJC_WEAK = YES; 709 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 710 | CLANG_WARN_BOOL_CONVERSION = YES; 711 | CLANG_WARN_COMMA = YES; 712 | CLANG_WARN_CONSTANT_CONVERSION = YES; 713 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 714 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 715 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 716 | CLANG_WARN_EMPTY_BODY = YES; 717 | CLANG_WARN_ENUM_CONVERSION = YES; 718 | CLANG_WARN_INFINITE_RECURSION = YES; 719 | CLANG_WARN_INT_CONVERSION = YES; 720 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 721 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 722 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 723 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 724 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 725 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 726 | CLANG_WARN_STRICT_PROTOTYPES = YES; 727 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 728 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 729 | CLANG_WARN_UNREACHABLE_CODE = YES; 730 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 731 | COPY_PHASE_STRIP = NO; 732 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 733 | ENABLE_NS_ASSERTIONS = NO; 734 | ENABLE_STRICT_OBJC_MSGSEND = YES; 735 | GCC_C_LANGUAGE_STANDARD = gnu11; 736 | GCC_NO_COMMON_BLOCKS = YES; 737 | GCC_PREPROCESSOR_DEFINITIONS = ( 738 | "POD_CONFIGURATION_RELEASE=1", 739 | "$(inherited)", 740 | ); 741 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 742 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 743 | GCC_WARN_UNDECLARED_SELECTOR = YES; 744 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 745 | GCC_WARN_UNUSED_FUNCTION = YES; 746 | GCC_WARN_UNUSED_VARIABLE = YES; 747 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 748 | MTL_ENABLE_DEBUG_INFO = NO; 749 | MTL_FAST_MATH = YES; 750 | PRODUCT_NAME = "$(TARGET_NAME)"; 751 | STRIP_INSTALLED_PRODUCT = NO; 752 | SWIFT_COMPILATION_MODE = wholemodule; 753 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 754 | SWIFT_VERSION = 5.0; 755 | SYMROOT = "${SRCROOT}/../build"; 756 | }; 757 | name = Release; 758 | }; 759 | 9061ECDAB8CC7C01972FAD12BB1A8A69 /* Debug */ = { 760 | isa = XCBuildConfiguration; 761 | baseConfigurationReference = 95B09EA82E7AF9ACCCCAF3E55C859116 /* shared.debug.xcconfig */; 762 | buildSettings = { 763 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 764 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 765 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 766 | LD_RUNPATH_SEARCH_PATHS = ( 767 | "$(inherited)", 768 | "@executable_path/Frameworks", 769 | ); 770 | SDKROOT = iphoneos; 771 | TARGETED_DEVICE_FAMILY = "1,2"; 772 | }; 773 | name = Debug; 774 | }; 775 | F646A25B2353BEFBCFF3A64D5B3C2C75 /* Release */ = { 776 | isa = XCBuildConfiguration; 777 | baseConfigurationReference = 14F3E0BE1549710890F51EB8800CBDE3 /* Pods-JokesApp.release.xcconfig */; 778 | buildSettings = { 779 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 780 | CLANG_ENABLE_OBJC_WEAK = NO; 781 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 782 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 783 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 784 | CURRENT_PROJECT_VERSION = 1; 785 | DEFINES_MODULE = YES; 786 | DYLIB_COMPATIBILITY_VERSION = 1; 787 | DYLIB_CURRENT_VERSION = 1; 788 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 789 | INFOPLIST_FILE = "Target Support Files/Pods-JokesApp/Pods-JokesApp-Info.plist"; 790 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 791 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 792 | LD_RUNPATH_SEARCH_PATHS = ( 793 | "$(inherited)", 794 | "@executable_path/Frameworks", 795 | "@loader_path/Frameworks", 796 | ); 797 | MACH_O_TYPE = staticlib; 798 | MODULEMAP_FILE = "Target Support Files/Pods-JokesApp/Pods-JokesApp.modulemap"; 799 | OTHER_LDFLAGS = ""; 800 | OTHER_LIBTOOLFLAGS = ""; 801 | PODS_ROOT = "$(SRCROOT)"; 802 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 803 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 804 | SDKROOT = iphoneos; 805 | SKIP_INSTALL = YES; 806 | TARGETED_DEVICE_FAMILY = "1,2"; 807 | VALIDATE_PRODUCT = YES; 808 | VERSIONING_SYSTEM = "apple-generic"; 809 | VERSION_INFO_PREFIX = ""; 810 | }; 811 | name = Release; 812 | }; 813 | FDDF56E3306910672C2276B55C3D4BB4 /* Release */ = { 814 | isa = XCBuildConfiguration; 815 | baseConfigurationReference = 708393D972AFAF28C3EA72D57A8DCD16 /* Pods-JokesAppTests.release.xcconfig */; 816 | buildSettings = { 817 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 818 | CLANG_ENABLE_OBJC_WEAK = NO; 819 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 820 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 821 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 822 | CURRENT_PROJECT_VERSION = 1; 823 | DEFINES_MODULE = YES; 824 | DYLIB_COMPATIBILITY_VERSION = 1; 825 | DYLIB_CURRENT_VERSION = 1; 826 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 827 | INFOPLIST_FILE = "Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests-Info.plist"; 828 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 829 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 830 | LD_RUNPATH_SEARCH_PATHS = ( 831 | "$(inherited)", 832 | "@executable_path/Frameworks", 833 | "@loader_path/Frameworks", 834 | ); 835 | MACH_O_TYPE = staticlib; 836 | MODULEMAP_FILE = "Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests.modulemap"; 837 | OTHER_LDFLAGS = ""; 838 | OTHER_LIBTOOLFLAGS = ""; 839 | PODS_ROOT = "$(SRCROOT)"; 840 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 841 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 842 | SDKROOT = iphoneos; 843 | SKIP_INSTALL = YES; 844 | TARGETED_DEVICE_FAMILY = "1,2"; 845 | VALIDATE_PRODUCT = YES; 846 | VERSIONING_SYSTEM = "apple-generic"; 847 | VERSION_INFO_PREFIX = ""; 848 | }; 849 | name = Release; 850 | }; 851 | /* End XCBuildConfiguration section */ 852 | 853 | /* Begin XCConfigurationList section */ 854 | 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { 855 | isa = XCConfigurationList; 856 | buildConfigurations = ( 857 | 4BC7450F9457737EE3E637BA155B56F7 /* Debug */, 858 | 8B5A46FF8D3C1289CDEE3BAFACABCD2A /* Release */, 859 | ); 860 | defaultConfigurationIsVisible = 0; 861 | defaultConfigurationName = Release; 862 | }; 863 | 7F8C885627680300F1E6F98C1FB57356 /* Build configuration list for PBXNativeTarget "Pods-JokesApp-JokesAppUITests" */ = { 864 | isa = XCConfigurationList; 865 | buildConfigurations = ( 866 | 16A66CB8339521257E84A7FBE66B934F /* Debug */, 867 | 7DF8CE9EF69CDEDE8B1B025D88D9D322 /* Release */, 868 | ); 869 | defaultConfigurationIsVisible = 0; 870 | defaultConfigurationName = Release; 871 | }; 872 | A4E6ED1E049DD76E34F5B81B6948CB67 /* Build configuration list for PBXNativeTarget "Pods-JokesAppTests" */ = { 873 | isa = XCConfigurationList; 874 | buildConfigurations = ( 875 | 4FAC2C9C8C4A06122802ADD9FD921FBB /* Debug */, 876 | FDDF56E3306910672C2276B55C3D4BB4 /* Release */, 877 | ); 878 | defaultConfigurationIsVisible = 0; 879 | defaultConfigurationName = Release; 880 | }; 881 | C12F82084A1D789106266CAAF7274FD2 /* Build configuration list for PBXAggregateTarget "shared" */ = { 882 | isa = XCConfigurationList; 883 | buildConfigurations = ( 884 | 9061ECDAB8CC7C01972FAD12BB1A8A69 /* Debug */, 885 | 227B446DBBD8A4398C780CCEC3A058D7 /* Release */, 886 | ); 887 | defaultConfigurationIsVisible = 0; 888 | defaultConfigurationName = Release; 889 | }; 890 | F56F7B9E213404FCC59ABADB8EFBA9F4 /* Build configuration list for PBXNativeTarget "Pods-JokesApp" */ = { 891 | isa = XCConfigurationList; 892 | buildConfigurations = ( 893 | 52AFFB3B12CA28E60E0860748C36F10F /* Debug */, 894 | F646A25B2353BEFBCFF3A64D5B3C2C75 /* Release */, 895 | ); 896 | defaultConfigurationIsVisible = 0; 897 | defaultConfigurationName = Release; 898 | }; 899 | /* End XCConfigurationList section */ 900 | }; 901 | rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; 902 | } 903 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_JokesApp_JokesAppUITests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_JokesApp_JokesAppUITests 5 | @end 6 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_JokesApp_JokesAppUITestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_JokesApp_JokesAppUITestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -framework "JokesShared" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_JokesApp_JokesAppUITests { 2 | umbrella header "Pods-JokesApp-JokesAppUITests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp-JokesAppUITests/Pods-JokesApp-JokesAppUITests.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -framework "JokesShared" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp/Pods-JokesApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp/Pods-JokesApp-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp/Pods-JokesApp-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp/Pods-JokesApp-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_JokesApp : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_JokesApp 5 | @end 6 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp/Pods-JokesApp-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_JokesAppVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_JokesAppVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp/Pods-JokesApp.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -framework "JokesShared" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp/Pods-JokesApp.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_JokesApp { 2 | umbrella header "Pods-JokesApp-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesApp/Pods-JokesApp.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -framework "JokesShared" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_JokesAppTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_JokesAppTests 5 | @end 6 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_JokesAppTestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_JokesAppTestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -l"c++" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_JokesAppTests { 2 | umbrella header "Pods-JokesAppTests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/Pods-JokesAppTests/Pods-JokesAppTests.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -l"c++" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/shared/shared.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/shared 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | KOTLIN_TARGET[sdk=appletvos*] = tvos_arm64 6 | KOTLIN_TARGET[sdk=appletvsimulator*] = tvos_x64 7 | KOTLIN_TARGET[sdk=iphoneos*] = ios_arm 8 | KOTLIN_TARGET[sdk=iphonesimulator*] = ios_x64 9 | KOTLIN_TARGET[sdk=macosx*] = macos_x64 10 | KOTLIN_TARGET[sdk=watchos*] = watchos_arm 11 | KOTLIN_TARGET[sdk=watchsimulator*] = watchos_x64 12 | PODS_BUILD_DIR = ${BUILD_DIR} 13 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 14 | PODS_ROOT = ${SRCROOT} 15 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../shared 16 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 17 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 18 | SKIP_INSTALL = YES 19 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 20 | -------------------------------------------------------------------------------- /iosApp/Pods/Target Support Files/shared/shared.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/shared 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | KOTLIN_TARGET[sdk=appletvos*] = tvos_arm64 6 | KOTLIN_TARGET[sdk=appletvsimulator*] = tvos_x64 7 | KOTLIN_TARGET[sdk=iphoneos*] = ios_arm 8 | KOTLIN_TARGET[sdk=iphonesimulator*] = ios_x64 9 | KOTLIN_TARGET[sdk=macosx*] = macos_x64 10 | KOTLIN_TARGET[sdk=watchos*] = watchos_arm 11 | KOTLIN_TARGET[sdk=watchsimulator*] = watchos_x64 12 | PODS_BUILD_DIR = ${BUILD_DIR} 13 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 14 | PODS_ROOT = ${SRCROOT} 15 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../shared 16 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 17 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 18 | SKIP_INSTALL = YES 19 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 20 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | } 7 | } 8 | 9 | rootProject.name = "JokesKMM" 10 | include(":androidApp") 11 | include(":shared") -------------------------------------------------------------------------------- /shared/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget 2 | 3 | plugins { 4 | id("com.android.library") 5 | kotlin("multiplatform") 6 | kotlin("native.cocoapods") 7 | kotlin("plugin.serialization") version "1.5.10" 8 | id("com.squareup.sqldelight") 9 | 10 | } 11 | 12 | sqldelight { 13 | database("JokesDatabase") { 14 | packageName = "com.kurt.jokes" 15 | } 16 | } 17 | 18 | version = "1.0.0" 19 | 20 | val coroutines: String by project 21 | val ktor: String by project 22 | val sqldelight: String by project 23 | val serialization: String by project 24 | 25 | kotlin { 26 | cocoapods { 27 | summary = "Shared module for Android and iOS" 28 | homepage = "Link to a Kotlin/Native module homepage" 29 | frameworkName = "JokesShared" 30 | } 31 | 32 | val iosTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget = 33 | if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true) 34 | ::iosArm64 35 | else 36 | ::iosX64 37 | 38 | android() 39 | iosTarget("ios") {} 40 | 41 | sourceSets { 42 | val commonMain by getting { 43 | dependencies { 44 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines") 45 | implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serialization") 46 | implementation("io.ktor:ktor-client-json:$ktor") 47 | implementation("io.ktor:ktor-client-serialization:$ktor") 48 | implementation("io.ktor:ktor-client-core:$ktor") 49 | implementation("io.ktor:ktor-client-cio:$ktor") 50 | } 51 | } 52 | 53 | val iosMain by getting { 54 | dependencies { 55 | implementation("io.ktor:ktor-client-ios:$ktor") 56 | implementation("com.squareup.sqldelight:native-driver:$sqldelight") 57 | } 58 | } 59 | 60 | val commonTest by getting { 61 | dependencies { 62 | implementation("org.jetbrains.kotlin:kotlin-test-common") 63 | implementation("org.jetbrains.kotlin:kotlin-test-annotations-common") 64 | } 65 | } 66 | 67 | val androidTest by getting { 68 | dependencies { 69 | implementation("org.jetbrains.kotlin:kotlin-test") 70 | implementation("org.jetbrains.kotlin:kotlin-test-junit") 71 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines") 72 | } 73 | } 74 | 75 | val androidMain by getting { 76 | dependencies { 77 | implementation("io.ktor:ktor-client-android:$ktor") 78 | implementation("com.squareup.sqldelight:android-driver:$sqldelight") 79 | 80 | // LiveData and ViewModel 81 | val lifecycleVersion = "2.2.0" 82 | implementation("androidx.lifecycle:lifecycle-extensions:$lifecycleVersion") 83 | implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion") 84 | } 85 | } 86 | } 87 | } 88 | 89 | android { 90 | compileSdkVersion(29) 91 | defaultConfig { 92 | minSdkVersion(21) 93 | targetSdkVersion(29) 94 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 95 | } 96 | 97 | buildTypes { 98 | getByName("release") { 99 | isMinifyEnabled = true 100 | consumerProguardFiles("consumer-rules.pro") 101 | } 102 | } 103 | 104 | compileOptions { 105 | sourceCompatibility = JavaVersion.VERSION_1_8 106 | targetCompatibility = JavaVersion.VERSION_1_8 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /shared/shared.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'shared' 3 | spec.version = '1.0.0' 4 | spec.homepage = 'Link to a Kotlin/Native module homepage' 5 | spec.source = { :git => "Not Published", :tag => "Cocoapods/#{spec.name}/#{spec.version}" } 6 | spec.authors = '' 7 | spec.license = '' 8 | spec.summary = 'Shared module for Android and iOS' 9 | 10 | spec.static_framework = true 11 | spec.vendored_frameworks = "build/cocoapods/framework/JokesShared.framework" 12 | spec.libraries = "c++" 13 | spec.module_name = "#{spec.name}_umbrella" 14 | 15 | 16 | 17 | 18 | 19 | spec.pod_target_xcconfig = { 20 | 'KOTLIN_TARGET[sdk=iphonesimulator*]' => 'ios_x64', 21 | 'KOTLIN_TARGET[sdk=iphoneos*]' => 'ios_arm', 22 | 'KOTLIN_TARGET[sdk=watchsimulator*]' => 'watchos_x64', 23 | 'KOTLIN_TARGET[sdk=watchos*]' => 'watchos_arm', 24 | 'KOTLIN_TARGET[sdk=appletvsimulator*]' => 'tvos_x64', 25 | 'KOTLIN_TARGET[sdk=appletvos*]' => 'tvos_arm64', 26 | 'KOTLIN_TARGET[sdk=macosx*]' => 'macos_x64' 27 | } 28 | 29 | spec.script_phases = [ 30 | { 31 | :name => 'Build shared', 32 | :execution_position => :before_compile, 33 | :shell_path => '/bin/sh', 34 | :script => <<-SCRIPT 35 | set -ev 36 | REPO_ROOT="$PODS_TARGET_SRCROOT" 37 | "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" :shared:syncFramework \ 38 | -Pkotlin.native.cocoapods.target=$KOTLIN_TARGET \ 39 | -Pkotlin.native.cocoapods.configuration=$CONFIGURATION \ 40 | -Pkotlin.native.cocoapods.cflags="$OTHER_CFLAGS" \ 41 | -Pkotlin.native.cocoapods.paths.headers="$HEADER_SEARCH_PATHS" \ 42 | -Pkotlin.native.cocoapods.paths.frameworks="$FRAMEWORK_SEARCH_PATHS" 43 | SCRIPT 44 | } 45 | ] 46 | end -------------------------------------------------------------------------------- /shared/src/androidMain/kotlin/com/kurt/jokes/mobile/CommonAndroid.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | actual fun platformName(): String { 4 | return "Android" 5 | } -------------------------------------------------------------------------------- /shared/src/androidMain/kotlin/com/kurt/jokes/mobile/data/local/JokesDatabaseDriver.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.data.local 2 | 3 | import android.content.Context 4 | import com.kurt.jokes.JokesDatabase 5 | import com.squareup.sqldelight.android.AndroidSqliteDriver 6 | import com.squareup.sqldelight.db.SqlDriver 7 | 8 | actual object JokesDatabaseDriver { 9 | lateinit var context: Context 10 | 11 | actual fun getDriver(): SqlDriver { 12 | return AndroidSqliteDriver(JokesDatabase.Schema, context, "asdf.db") 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /shared/src/androidMain/kotlin/com/kurt/jokes/mobile/presentation/base/BaseViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.base 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.viewModelScope 5 | import kotlinx.coroutines.CoroutineScope 6 | 7 | /** 8 | * Copyright 2020, Kurt Renzo Acosta, All rights reserved. 9 | * 10 | * @author Kurt Renzo Acosta 11 | * @since 01/01/2020 12 | */ 13 | 14 | actual open class BaseViewModel actual constructor(): ViewModel() { 15 | actual val clientScope: CoroutineScope = viewModelScope 16 | actual override fun onCleared() { 17 | super.onCleared() 18 | } 19 | } -------------------------------------------------------------------------------- /shared/src/androidMain/kotlin/com/kurt/jokes/mobile/presentation/base/Dispatchers.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.base 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.Dispatchers 5 | 6 | actual var mainDispatcher: CoroutineDispatcher = Dispatchers.Main 7 | actual val ioDispatcher: CoroutineDispatcher = Dispatchers.IO -------------------------------------------------------------------------------- /shared/src/androidMain/kotlin/com/kurt/jokes/mobile/presentation/features/jokes/JokesViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.features.jokes 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider 5 | import kotlinx.coroutines.ExperimentalCoroutinesApi 6 | 7 | @ExperimentalCoroutinesApi 8 | class JokesViewModelFactory : ViewModelProvider.NewInstanceFactory() { 9 | @Suppress("UNCHECKED_CAST") 10 | override fun create(modelClass: Class): T { 11 | return JokesViewModel.create() as T 12 | } 13 | } -------------------------------------------------------------------------------- /shared/src/androidTest/kotlin/com/kurt/jokes/mobile/CommonTest.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | import org.junit.Rule 5 | 6 | actual open class CommonTest { 7 | @get:Rule 8 | val rule = CoroutineTestRule() 9 | actual fun runBlocking(block: suspend CoroutineScope.() -> Unit) = kotlinx.coroutines.runBlocking { 10 | block() 11 | } 12 | } -------------------------------------------------------------------------------- /shared/src/androidTest/kotlin/com/kurt/jokes/mobile/CommonTestCoroutineDispatcher.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import kotlinx.coroutines.test.TestCoroutineDispatcher 4 | 5 | /** 6 | * Copyright 2020, Kurt Renzo Acosta, All rights reserved. 7 | * 8 | * @author Kurt Renzo Acosta 9 | * @since 07/18/2020 10 | */ 11 | 12 | actual typealias CommonTestCoroutineDispatcher = TestCoroutineDispatcher -------------------------------------------------------------------------------- /shared/src/androidTest/kotlin/com/kurt/jokes/mobile/CoroutineTestRule.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import kotlinx.coroutines.Dispatchers 4 | import kotlinx.coroutines.ExperimentalCoroutinesApi 5 | import kotlinx.coroutines.test.TestCoroutineDispatcher 6 | import kotlinx.coroutines.test.resetMain 7 | import kotlinx.coroutines.test.setMain 8 | import org.junit.rules.TestWatcher 9 | import org.junit.runner.Description 10 | 11 | @OptIn(ExperimentalCoroutinesApi::class) 12 | class CoroutineTestRule( 13 | private val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher() 14 | ) : TestWatcher() { 15 | override fun starting(description: Description?) { 16 | super.starting(description) 17 | Dispatchers.setMain(testDispatcher) 18 | } 19 | 20 | override fun finished(description: Description?) { 21 | super.finished(description) 22 | Dispatchers.resetMain() 23 | testDispatcher.cleanupTestCoroutines() 24 | } 25 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/Common.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | expect fun platformName(): String 4 | 5 | fun createApplicationScreenMessage() : String { 6 | return "Kotlin Rocks on ${platformName()}" 7 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/ServiceLocator.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import com.kurt.jokes.JokesDatabase 4 | import com.kurt.jokes.mobile.data.RealJokesRepository 5 | import com.kurt.jokes.mobile.data.local.JokesDatabaseDriver 6 | import com.kurt.jokes.mobile.data.local.JokesLocalSource 7 | import com.kurt.jokes.mobile.data.remote.JokesRemoteSource 8 | import com.kurt.jokes.mobile.domain.entities.Joke 9 | import com.kurt.jokes.mobile.domain.repositories.JokesRepository 10 | import io.ktor.client.* 11 | import io.ktor.client.features.json.* 12 | import io.ktor.client.features.json.serializer.* 13 | import kotlin.native.concurrent.ThreadLocal 14 | import kotlin.reflect.typeOf 15 | 16 | @ThreadLocal 17 | object ServiceLocator { 18 | // Data 19 | @OptIn(ExperimentalStdlibApi::class) 20 | private val client = HttpClient { 21 | install(JsonFeature) { 22 | serializer = KotlinxSerializer().apply { 23 | typeOf>() 24 | } 25 | } 26 | } 27 | private val jokesLocalSource = JokesLocalSource(JokesDatabase(JokesDatabaseDriver.getDriver())) 28 | private val jokesRemoteSource = JokesRemoteSource(client) 29 | val jokesRepository: JokesRepository = RealJokesRepository( 30 | jokesRemoteSource, 31 | jokesLocalSource 32 | ) 33 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/data/RealJokesRepository.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.data 2 | 3 | import com.kurt.jokes.mobile.data.local.JokesLocalSource 4 | import com.kurt.jokes.mobile.data.remote.JokesRemoteSource 5 | import com.kurt.jokes.mobile.domain.entities.Joke 6 | import com.kurt.jokes.mobile.domain.repositories.JokesRepository 7 | import com.kurt.jokes.mobile.presentation.base.ioDispatcher 8 | import kotlinx.coroutines.coroutineScope 9 | import kotlinx.coroutines.withContext 10 | 11 | class RealJokesRepository( 12 | private val jokesRemoteSource: JokesRemoteSource, 13 | private val jokesLocalSource: JokesLocalSource 14 | ) : JokesRepository { 15 | override suspend fun getJokes() = withContext(ioDispatcher) { 16 | try { 17 | val jokes = jokesRemoteSource.getJokes() 18 | jokesLocalSource.saveJokes(jokes) 19 | } catch (exception: Exception) { 20 | exception.printStackTrace() 21 | } 22 | jokesLocalSource.getJokes() 23 | } 24 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/data/local/JokesDatabaseDriver.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.data.local 2 | 3 | import com.squareup.sqldelight.db.SqlDriver 4 | 5 | expect object JokesDatabaseDriver { 6 | fun getDriver(): SqlDriver 7 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/data/local/JokesLocalSource.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.data.local 2 | 3 | import com.kurt.jokes.JokeDb 4 | import com.kurt.jokes.JokesDatabase 5 | import com.kurt.jokes.mobile.domain.entities.Joke 6 | 7 | class JokesLocalSource(private val db: JokesDatabase) { 8 | fun getJokes(): List { 9 | return db.jokeQueries.getAllJokes().executeAsList().map { 10 | Joke( 11 | id = it.id, 12 | setup = it.setup, 13 | punchline = it.punchline, 14 | type = it.type 15 | ) 16 | } 17 | } 18 | 19 | fun saveJokes(jokes: List) { 20 | jokes.forEach { 21 | db.jokeQueries.insertJoke( 22 | JokeDb( 23 | id = it.id, 24 | setup = it.setup, 25 | punchline = it.punchline, 26 | type = it.type 27 | ) 28 | ) 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/data/remote/JokesRemoteSource.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.data.remote 2 | 3 | import com.kurt.jokes.mobile.domain.entities.Joke 4 | import io.ktor.client.* 5 | import io.ktor.client.request.* 6 | 7 | @OptIn(ExperimentalStdlibApi::class) 8 | class JokesRemoteSource(private val client: HttpClient) { 9 | suspend fun getJokes(): List = 10 | client.get("https://official-joke-api.appspot.com/jokes/ten") 11 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/domain/entities/Joke.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.domain.entities 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Joke( 7 | val id: Long, 8 | val type: String, 9 | val setup: String, 10 | val punchline: String 11 | ) { 12 | var isPunchlineVisible = false 13 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/domain/repositories/JokesRepository.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.domain.repositories 2 | 3 | import com.kurt.jokes.mobile.domain.entities.Joke 4 | 5 | interface JokesRepository { 6 | suspend fun getJokes(): List 7 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/presentation/base/BaseViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.base 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | 5 | /** 6 | * Copyright 2020, Kurt Renzo Acosta, All rights reserved. 7 | * 8 | * @author Kurt Renzo Acosta 9 | * @since 01/01/2020 10 | */ 11 | 12 | expect open class BaseViewModel() { 13 | val clientScope: CoroutineScope 14 | protected open fun onCleared() 15 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/presentation/base/Dispatchers.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.base 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | 5 | expect var mainDispatcher: CoroutineDispatcher 6 | expect val ioDispatcher: CoroutineDispatcher -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/presentation/features/jokes/JokesViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.features.jokes 2 | 3 | import com.kurt.jokes.mobile.ServiceLocator 4 | import com.kurt.jokes.mobile.domain.entities.Joke 5 | import com.kurt.jokes.mobile.domain.repositories.JokesRepository 6 | import com.kurt.jokes.mobile.presentation.models.UiState 7 | import com.kurt.jokes.mobile.presentation.base.BaseViewModel 8 | import com.kurt.jokes.mobile.presentation.helpers.CommonFlow 9 | import com.kurt.jokes.mobile.presentation.helpers.asCommonFlow 10 | import kotlinx.coroutines.CoroutineExceptionHandler 11 | import kotlinx.coroutines.ExperimentalCoroutinesApi 12 | import kotlinx.coroutines.flow.MutableStateFlow 13 | import kotlinx.coroutines.flow.filterNotNull 14 | import kotlinx.coroutines.launch 15 | import kotlin.native.concurrent.ThreadLocal 16 | 17 | @OptIn(ExperimentalCoroutinesApi::class) 18 | class JokesViewModel(private val jokesRepository: JokesRepository) : BaseViewModel() { 19 | private val _jokes = MutableStateFlow(listOf()) 20 | val jokes: CommonFlow> get() = _jokes.asCommonFlow() 21 | 22 | private val _jokesState = MutableStateFlow(null) 23 | val jokesState: CommonFlow get() = _jokesState.filterNotNull().asCommonFlow() 24 | 25 | init { 26 | clientScope.launch(CoroutineExceptionHandler { _, throwable -> 27 | _jokesState.value = UiState.Error(throwable) 28 | }) { 29 | _jokesState.value = UiState.Loading 30 | _jokes.value = jokesRepository.getJokes() 31 | _jokesState.value = UiState.Success 32 | } 33 | } 34 | 35 | @ThreadLocal 36 | companion object { 37 | fun create() = JokesViewModel(ServiceLocator.jokesRepository) 38 | } 39 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/presentation/helpers/FlowHelpers.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.helpers 2 | 3 | import com.kurt.jokes.mobile.presentation.base.mainDispatcher 4 | import io.ktor.utils.io.core.Closeable 5 | import kotlinx.coroutines.* 6 | import kotlinx.coroutines.flow.* 7 | 8 | /** 9 | * Copyright 2020, Kurt Renzo Acosta, All rights reserved. 10 | * 11 | * @author Kurt Renzo Acosta 12 | * @since 01/01/2020 13 | */ 14 | 15 | fun Flow.asCommonFlow(): CommonFlow = CommonFlow(this) 16 | class CommonFlow(private val origin: Flow) : Flow by origin { 17 | fun watch(block: (T) -> Unit): Closeable { 18 | val job = Job() 19 | 20 | onEach { 21 | block(it) 22 | }.launchIn(CoroutineScope(mainDispatcher + job)) 23 | 24 | return object : Closeable { 25 | override fun close() { 26 | job.cancel() 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /shared/src/commonMain/kotlin/com/kurt/jokes/mobile/presentation/models/UiState.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.models 2 | 3 | sealed class UiState { 4 | object Success : UiState() 5 | object Loading : UiState() 6 | class Error(val throwable: Throwable) : UiState() 7 | } -------------------------------------------------------------------------------- /shared/src/commonMain/sqldelight/com/kurt/jokes/Joke.sq: -------------------------------------------------------------------------------- 1 | CREATE TABLE JokeDb ( 2 | id INTEGER NOT NULL, 3 | setup TEXT NOT NULL, 4 | punchline TEXT NOT NULL, 5 | type TEXT NOT NULL 6 | ); 7 | 8 | getAllJokes: 9 | SELECT * FROM JokeDb; 10 | 11 | insertJoke: 12 | INSERT INTO JokeDb (id, setup, punchline, type) 13 | VALUES ?; -------------------------------------------------------------------------------- /shared/src/commonTest/kotlin/com/kurt/jokes/mobile/CommonTest.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | 5 | expect open class CommonTest() { 6 | fun runBlocking(block: suspend CoroutineScope.() -> Unit) 7 | } -------------------------------------------------------------------------------- /shared/src/commonTest/kotlin/com/kurt/jokes/mobile/CommonTestCoroutineDispatcher.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | 5 | /** 6 | * Copyright 2020, Kurt Renzo Acosta, All rights reserved. 7 | * 8 | * @author Kurt Renzo Acosta 9 | * @since 07/18/2020 10 | */ 11 | 12 | expect class CommonTestCoroutineDispatcher() : CoroutineDispatcher -------------------------------------------------------------------------------- /shared/src/commonTest/kotlin/com/kurt/jokes/mobile/FakeJokesRepository.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import com.kurt.jokes.mobile.domain.entities.Joke 4 | import com.kurt.jokes.mobile.domain.repositories.JokesRepository 5 | 6 | class FakeJokesRepository : JokesRepository { 7 | override suspend fun getJokes(): List { 8 | return listOf( 9 | Joke(1, "joke", "joke", "joke") 10 | ) 11 | } 12 | } -------------------------------------------------------------------------------- /shared/src/commonTest/kotlin/com/kurt/jokes/mobile/JokesViewModelTest.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import com.kurt.jokes.mobile.presentation.base.mainDispatcher 4 | import com.kurt.jokes.mobile.presentation.features.jokes.JokesViewModel 5 | import kotlinx.coroutines.flow.first 6 | import kotlin.test.BeforeTest 7 | import kotlin.test.Test 8 | import kotlin.test.assertEquals 9 | 10 | class JokesViewModelTest : CommonTest() { 11 | private lateinit var viewModel: JokesViewModel 12 | 13 | @BeforeTest 14 | fun coroutinesSetup() { 15 | mainDispatcher = CommonTestCoroutineDispatcher() 16 | } 17 | 18 | private fun setup() { 19 | viewModel = JokesViewModel(FakeJokesRepository()) 20 | } 21 | 22 | @Test 23 | fun `should get jokes on start`() = runBlocking { 24 | // When - viewModel is created 25 | setup() 26 | 27 | // Then - it should have the list of jokes 28 | val jokes = viewModel.jokes.first() 29 | assertEquals(1, jokes.size) 30 | 31 | val firstJoke = jokes[0] 32 | assertEquals(1, firstJoke.id) 33 | assertEquals("joke", firstJoke.type) 34 | assertEquals("joke", firstJoke.setup) 35 | assertEquals("joke", firstJoke.punchline) 36 | } 37 | } -------------------------------------------------------------------------------- /shared/src/iosMain/kotlin/com/kurt/jokes/mobile/CommonIos.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | actual fun platformName(): String { 4 | return "iOS" 5 | } -------------------------------------------------------------------------------- /shared/src/iosMain/kotlin/com/kurt/jokes/mobile/data/local/JokesDatabaseDriver.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.data.local 2 | 3 | import com.kurt.jokes.JokesDatabase 4 | import com.squareup.sqldelight.db.SqlDriver 5 | import com.squareup.sqldelight.drivers.native.NativeSqliteDriver 6 | 7 | actual object JokesDatabaseDriver { 8 | actual fun getDriver(): SqlDriver = NativeSqliteDriver(JokesDatabase.Schema, "jokes.db") 9 | } -------------------------------------------------------------------------------- /shared/src/iosMain/kotlin/com/kurt/jokes/mobile/presentation/base/BaseViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.base 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | import kotlinx.coroutines.SupervisorJob 5 | import kotlinx.coroutines.cancelChildren 6 | 7 | /** 8 | * Copyright 2020, Kurt Renzo Acosta, All rights reserved. 9 | * 10 | * @author Kurt Renzo Acosta 11 | * @since 01/01/2020 12 | */ 13 | 14 | actual open class BaseViewModel actual constructor() { 15 | private val viewModelJob = SupervisorJob() 16 | val viewModelScope: CoroutineScope = CoroutineScope(ioDispatcher + viewModelJob) 17 | 18 | actual val clientScope: CoroutineScope = viewModelScope 19 | 20 | protected actual open fun onCleared() { 21 | viewModelJob.cancelChildren() 22 | } 23 | } -------------------------------------------------------------------------------- /shared/src/iosMain/kotlin/com/kurt/jokes/mobile/presentation/base/Dispatchers.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile.presentation.base 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.Dispatchers 5 | 6 | actual var mainDispatcher: CoroutineDispatcher = Dispatchers.Main 7 | actual val ioDispatcher: CoroutineDispatcher = Dispatchers.Main -------------------------------------------------------------------------------- /shared/src/iosTest/kotlin/com/kurt/jokes/mobile/CommonTest.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | 5 | actual open class CommonTest { 6 | actual fun runBlocking(block: suspend CoroutineScope.() -> Unit) = kotlinx.coroutines.runBlocking { 7 | block() 8 | } 9 | } -------------------------------------------------------------------------------- /shared/src/iosTest/kotlin/com/kurt/jokes/mobile/CommonTestCoroutineDispatcher.kt: -------------------------------------------------------------------------------- 1 | package com.kurt.jokes.mobile 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.Runnable 5 | import kotlin.coroutines.CoroutineContext 6 | 7 | /** 8 | * Copyright 2020, Kurt Renzo Acosta, All rights reserved. 9 | * 10 | * @author Kurt Renzo Acosta 11 | * @since 07/18/2020 12 | */ 13 | 14 | actual class CommonTestCoroutineDispatcher : CoroutineDispatcher() { 15 | override fun dispatch(context: CoroutineContext, block: Runnable) { 16 | block.run() 17 | } 18 | } -------------------------------------------------------------------------------- /shared/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------